feature: emojis! (#11857) 89305a5fed
* feature: emojis!

* fix: pr feedback

* fix: missed font asset

* fix: more missed fonts

* feature: harfbuzz 13.1.1

* fix: removed too much

* fix: cleanup

* fix: goldens changed by text

* harfbuzz: even more removed

* fix: re-add harfbuzz feature

* chore: rebaseline goldens

* chore: strip HB_NO_VAR_COMPOSITES

* more font tests

* chore: rebaseline d3d atomic

* chore: pixel6 goldens rebaseline

* fix: test path

Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head
index d6e279c..cc9d1b5 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-3eb4211852d4ca66c76c89fada97c9c226fff379
+89305a5fedb7a617c22dad6d7818c9dcc4f1cf84
diff --git a/dependencies/premake5_harfbuzz.lua b/dependencies/premake5_harfbuzz.lua
deleted file mode 100644
index 9926489..0000000
--- a/dependencies/premake5_harfbuzz.lua
+++ /dev/null
@@ -1,407 +0,0 @@
-require('setup_compiler')
-local dependency = require('dependency')
-harfbuzz = dependency.github('rive-app/harfbuzz', 'rive_10.1.0')
-
-workspace('rive')
-configurations({ 'debug', 'release' })
-
-project('rive_harfbuzz')
-do
-    kind('StaticLib')
-    language('C++')
-    cppdialect('C++17')
-    targetdir('%{cfg.system}/cache/bin/%{cfg.buildcfg}/')
-    objdir('%{cfg.system}/cache/obj/%{cfg.buildcfg}/')
-
-    includedirs({ '../', harfbuzz .. '/src' })
-
-    files({
-        harfbuzz .. '/src/hb-aat-layout-ankr-table.hh',
-        harfbuzz .. '/src/hb-aat-layout-bsln-table.hh',
-        harfbuzz .. '/src/hb-aat-layout-common.hh',
-        harfbuzz .. '/src/hb-aat-layout-feat-table.hh',
-        harfbuzz .. '/src/hb-aat-layout-just-table.hh',
-        harfbuzz .. '/src/hb-aat-layout-kerx-table.hh',
-        harfbuzz .. '/src/hb-aat-layout-morx-table.hh',
-        harfbuzz .. '/src/hb-aat-layout-opbd-table.hh',
-        harfbuzz .. '/src/hb-aat-layout-trak-table.hh',
-        harfbuzz .. '/src/hb-aat-layout.cc',
-        harfbuzz .. '/src/hb-aat-layout.hh',
-        harfbuzz .. '/src/hb-aat-ltag-table.hh',
-        harfbuzz .. '/src/hb-aat-map.cc',
-        harfbuzz .. '/src/hb-aat-map.hh',
-        harfbuzz .. '/src/hb-aat.h',
-        harfbuzz .. '/src/hb-algs.hh',
-        harfbuzz .. '/src/hb-array.hh',
-        harfbuzz .. '/src/hb-atomic.hh',
-        harfbuzz .. '/src/hb-bimap.hh',
-        harfbuzz .. '/src/hb-bit-page.hh',
-        harfbuzz .. '/src/hb-bit-set-invertible.hh',
-        harfbuzz .. '/src/hb-bit-set.hh',
-        harfbuzz .. '/src/hb-blob.cc',
-        harfbuzz .. '/src/hb-blob.hh',
-        harfbuzz .. '/src/hb-buffer-deserialize-json.hh',
-        harfbuzz .. '/src/hb-buffer-deserialize-text.hh',
-        harfbuzz .. '/src/hb-buffer-serialize.cc',
-        harfbuzz .. '/src/hb-buffer-verify.cc',
-        harfbuzz .. '/src/hb-buffer.cc',
-        harfbuzz .. '/src/hb-buffer.hh',
-        harfbuzz .. '/src/hb-cache.hh',
-        harfbuzz .. '/src/hb-cff-interp-common.hh',
-        harfbuzz .. '/src/hb-cff-interp-cs-common.hh',
-        harfbuzz .. '/src/hb-cff-interp-dict-common.hh',
-        harfbuzz .. '/src/hb-cff1-interp-cs.hh',
-        harfbuzz .. '/src/hb-cff2-interp-cs.hh',
-        harfbuzz .. '/src/hb-common.cc',
-        harfbuzz .. '/src/hb-config.hh',
-        harfbuzz .. '/src/hb-debug.hh',
-        harfbuzz .. '/src/hb-dispatch.hh',
-        harfbuzz .. '/src/hb-draw.cc',
-        harfbuzz .. '/src/hb-draw.h',
-        harfbuzz .. '/src/hb-draw.hh',
-        harfbuzz .. '/src/hb-face.cc',
-        harfbuzz .. '/src/hb-face.hh',
-        harfbuzz .. '/src/hb-font.cc',
-        harfbuzz .. '/src/hb-font.hh',
-        harfbuzz .. '/src/hb-iter.hh',
-        harfbuzz .. '/src/hb-kern.hh',
-        harfbuzz .. '/src/hb-machinery.hh',
-        harfbuzz .. '/src/hb-map.cc',
-        harfbuzz .. '/src/hb-map.hh',
-        harfbuzz .. '/src/hb-meta.hh',
-        harfbuzz .. '/src/hb-ms-feature-ranges.hh',
-        harfbuzz .. '/src/hb-mutex.hh',
-        harfbuzz .. '/src/hb-null.hh',
-        harfbuzz .. '/src/hb-number-parser.hh',
-        harfbuzz .. '/src/hb-number.cc',
-        harfbuzz .. '/src/hb-number.hh',
-        harfbuzz .. '/src/hb-object.hh',
-        harfbuzz .. '/src/hb-open-file.hh',
-        harfbuzz .. '/src/hb-open-type.hh',
-        harfbuzz .. '/src/hb-ot-cff-common.hh',
-        harfbuzz .. '/src/hb-ot-cff1-std-str.hh',
-        harfbuzz .. '/src/hb-ot-cff1-table.cc',
-        harfbuzz .. '/src/hb-ot-cff1-table.hh',
-        harfbuzz .. '/src/hb-ot-cff2-table.cc',
-        harfbuzz .. '/src/hb-ot-cff2-table.hh',
-        harfbuzz .. '/src/hb-ot-cmap-table.hh',
-        harfbuzz .. '/src/hb-ot-color-cbdt-table.hh',
-        harfbuzz .. '/src/hb-ot-color-colr-table.hh',
-        harfbuzz .. '/src/hb-ot-color-colrv1-closure.hh',
-        harfbuzz .. '/src/hb-ot-color-cpal-table.hh',
-        harfbuzz .. '/src/hb-ot-color-sbix-table.hh',
-        harfbuzz .. '/src/hb-ot-color-svg-table.hh',
-        harfbuzz .. '/src/hb-ot-color.cc',
-        harfbuzz .. '/src/hb-ot-color.h',
-        harfbuzz .. '/src/hb-ot-deprecated.h',
-        harfbuzz .. '/src/hb-ot-face-table-list.hh',
-        harfbuzz .. '/src/hb-ot-face.cc',
-        harfbuzz .. '/src/hb-ot-face.hh',
-        harfbuzz .. '/src/hb-ot-font.cc',
-        harfbuzz .. '/src/hb-ot-gasp-table.hh',
-        harfbuzz .. '/src/hb-ot-glyf-table.hh',
-        harfbuzz .. '/src/hb-ot-hdmx-table.hh',
-        harfbuzz .. '/src/hb-ot-head-table.hh',
-        harfbuzz .. '/src/hb-ot-hhea-table.hh',
-        harfbuzz .. '/src/hb-ot-hmtx-table.hh',
-        harfbuzz .. '/src/hb-ot-kern-table.hh',
-        harfbuzz .. '/src/hb-ot-layout-base-table.hh',
-        harfbuzz .. '/src/hb-ot-layout-common.hh',
-        harfbuzz .. '/src/hb-ot-layout-gdef-table.hh',
-        harfbuzz .. '/src/hb-ot-layout-gpos-table.hh',
-        harfbuzz .. '/src/hb-ot-layout-gsub-table.hh',
-        harfbuzz .. '/src/hb-ot-layout-gsubgpos.hh',
-        harfbuzz .. '/src/hb-ot-layout-jstf-table.hh',
-        harfbuzz .. '/src/hb-ot-layout.cc',
-        harfbuzz .. '/src/hb-ot-layout.hh',
-        harfbuzz .. '/src/hb-ot-map.cc',
-        harfbuzz .. '/src/hb-ot-map.hh',
-        harfbuzz .. '/src/hb-ot-math-table.hh',
-        harfbuzz .. '/src/hb-ot-math.cc',
-        harfbuzz .. '/src/hb-ot-maxp-table.hh',
-        harfbuzz .. '/src/hb-ot-meta-table.hh',
-        harfbuzz .. '/src/hb-ot-meta.cc',
-        harfbuzz .. '/src/hb-ot-meta.h',
-        harfbuzz .. '/src/hb-ot-metrics.cc',
-        harfbuzz .. '/src/hb-ot-metrics.hh',
-        harfbuzz .. '/src/hb-ot-name-language-static.hh',
-        harfbuzz .. '/src/hb-ot-name-language.hh',
-        harfbuzz .. '/src/hb-ot-name-table.hh',
-        harfbuzz .. '/src/hb-ot-name.cc',
-        harfbuzz .. '/src/hb-ot-name.h',
-        harfbuzz .. '/src/hb-ot-os2-table.hh',
-        harfbuzz .. '/src/hb-ot-os2-unicode-ranges.hh',
-        harfbuzz .. '/src/hb-ot-post-macroman.hh',
-        harfbuzz .. '/src/hb-ot-post-table-v2subset.hh',
-        harfbuzz .. '/src/hb-ot-post-table.hh',
-        harfbuzz .. '/src/hb-ot-shaper-arabic-fallback.hh',
-        harfbuzz .. '/src/hb-ot-shaper-arabic-joining-list.hh',
-        harfbuzz .. '/src/hb-ot-shaper-arabic-pua.hh',
-        harfbuzz .. '/src/hb-ot-shaper-arabic-table.hh',
-        harfbuzz .. '/src/hb-ot-shaper-arabic-win1256.hh',
-        harfbuzz .. '/src/hb-ot-shaper-arabic.cc',
-        harfbuzz .. '/src/hb-ot-shaper-arabic.hh',
-        harfbuzz .. '/src/hb-ot-shaper-default.cc',
-        harfbuzz .. '/src/hb-ot-shaper-hangul.cc',
-        harfbuzz .. '/src/hb-ot-shaper-hebrew.cc',
-        harfbuzz .. '/src/hb-ot-shaper-indic-table.cc',
-        harfbuzz .. '/src/hb-ot-shaper-indic.cc',
-        harfbuzz .. '/src/hb-ot-shaper-indic.hh',
-        harfbuzz .. '/src/hb-ot-shaper-khmer.cc',
-        harfbuzz .. '/src/hb-ot-shaper-myanmar.cc',
-        harfbuzz .. '/src/hb-ot-shaper-syllabic.cc',
-        harfbuzz .. '/src/hb-ot-shaper-syllabic.hh',
-        harfbuzz .. '/src/hb-ot-shaper-thai.cc',
-        harfbuzz .. '/src/hb-ot-shaper-use-table.hh',
-        harfbuzz .. '/src/hb-ot-shaper-use.cc',
-        harfbuzz .. '/src/hb-ot-shaper-vowel-constraints.cc',
-        harfbuzz .. '/src/hb-ot-shaper-vowel-constraints.hh',
-        harfbuzz .. '/src/hb-ot-shaper.hh',
-        harfbuzz .. '/src/hb-ot-shaper-indic-machine.hh',
-        harfbuzz .. '/src/hb-ot-shaper-khmer-machine.hh',
-        harfbuzz .. '/src/hb-ot-shaper-myanmar-machine.hh',
-        harfbuzz .. '/src/hb-ot-shaper-use-machine.hh',
-        harfbuzz .. '/src/hb-ot-shape-fallback.cc',
-        harfbuzz .. '/src/hb-ot-shape-fallback.hh',
-        harfbuzz .. '/src/hb-ot-shape-normalize.cc',
-        harfbuzz .. '/src/hb-ot-shape-normalize.hh',
-        harfbuzz .. '/src/hb-ot-shape.cc',
-        harfbuzz .. '/src/hb-ot-shape.hh',
-        harfbuzz .. '/src/hb-ot-stat-table.hh',
-        harfbuzz .. '/src/hb-ot-tag-table.hh',
-        harfbuzz .. '/src/hb-ot-tag.cc',
-        harfbuzz .. '/src/hb-ot-var-avar-table.hh',
-        harfbuzz .. '/src/hb-ot-var-common.hh',
-        harfbuzz .. '/src/hb-ot-var-fvar-table.hh',
-        harfbuzz .. '/src/hb-ot-var-gvar-table.hh',
-        harfbuzz .. '/src/hb-ot-var-hvar-table.hh',
-        harfbuzz .. '/src/hb-ot-var-mvar-table.hh',
-        harfbuzz .. '/src/hb-ot-var.cc',
-        harfbuzz .. '/src/hb-ot-vorg-table.hh',
-        harfbuzz .. '/src/hb-pool.hh',
-        harfbuzz .. '/src/hb-priority-queue.hh',
-        harfbuzz .. '/src/hb-repacker.hh',
-        harfbuzz .. '/src/hb-sanitize.hh',
-        harfbuzz .. '/src/hb-serialize.hh',
-        harfbuzz .. '/src/hb-set-digest.hh',
-        harfbuzz .. '/src/hb-set.cc',
-        harfbuzz .. '/src/hb-set.hh',
-        harfbuzz .. '/src/hb-shape-plan.cc',
-        harfbuzz .. '/src/hb-shape-plan.hh',
-        harfbuzz .. '/src/hb-shape.cc',
-        harfbuzz .. '/src/hb-shaper-impl.hh',
-        harfbuzz .. '/src/hb-shaper-list.hh',
-        harfbuzz .. '/src/hb-shaper.cc',
-        harfbuzz .. '/src/hb-shaper.hh',
-        harfbuzz .. '/src/hb-static.cc',
-        harfbuzz .. '/src/hb-string-array.hh',
-        harfbuzz .. '/src/hb-subset-cff-common.cc',
-        harfbuzz .. '/src/hb-subset-cff-common.hh',
-        harfbuzz .. '/src/hb-subset-cff1.cc',
-        harfbuzz .. '/src/hb-subset-cff1.hh',
-        harfbuzz .. '/src/hb-subset-cff2.cc',
-        harfbuzz .. '/src/hb-subset-cff2.hh',
-        harfbuzz .. '/src/hb-subset-input.cc',
-        harfbuzz .. '/src/hb-subset-input.hh',
-        harfbuzz .. '/src/hb-subset-plan.cc',
-        harfbuzz .. '/src/hb-subset-plan.hh',
-        harfbuzz .. '/src/hb-subset-repacker.cc',
-        harfbuzz .. '/src/hb-subset-repacker.h',
-        harfbuzz .. '/src/hb-subset.cc',
-        harfbuzz .. '/src/hb-subset.hh',
-        harfbuzz .. '/src/hb-ucd-table.hh',
-        harfbuzz .. '/src/hb-ucd.cc',
-        harfbuzz .. '/src/hb-unicode-emoji-table.hh',
-        harfbuzz .. '/src/hb-unicode.cc',
-        harfbuzz .. '/src/hb-unicode.hh',
-        harfbuzz .. '/src/hb-utf.hh',
-        harfbuzz .. '/src/hb-vector.hh',
-        harfbuzz .. '/src/hb.hh',
-        harfbuzz .. '/src/graph/gsubgpos-context.cc',
-        harfbuzz .. '/src/hb-paint.cc',
-        harfbuzz .. '/src/hb-paint-extents.cc',
-        harfbuzz .. '/src/hb-outline.cc',
-        harfbuzz .. '/src/hb-style.h',
-        harfbuzz .. '/src/hb-style.cc',
-    })
-
-    warnings('Off')
-
-    defines({
-        'HAVE_OT',
-        'HB_NO_FALLBACK_SHAPE',
-        'HB_NO_WIN1256',
-        'HB_NO_EXTERN_HELPERS',
-        'HB_DISABLE_DEPRECATED',
-        'HB_NO_COLOR',
-        'HB_NO_BITMAP',
-        'HB_NO_BUFFER_SERIALIZE',
-        'HB_NO_SETLOCALE',
-        'HB_NO_VERTICAL',
-        'HB_NO_LAYOUT_COLLECT_GLYPHS',
-        'HB_NO_LAYOUT_RARELY_USED',
-        'HB_NO_LAYOUT_UNUSED',
-        'HB_NO_OT_FONT_GLYPH_NAMES',
-    })
-
-    filter('system:emscripten')
-    do
-        buildoptions({ '-pthread' })
-    end
-
-    filter('toolset:clang')
-    do
-        fatalwarnings { "All" }
-        buildoptions({
-            '-Werror=format',
-            '-Wimplicit-int-conversion',
-            '-Werror=vla',
-        })
-    end
-    filter('toolset:msc')
-    do
-        buildoptions({
-            '/bigobj',
-        })
-    end
-
-    filter('configurations:debug')
-    do
-        defines({ 'DEBUG' })
-        symbols('On')
-    end
-
-    filter('configurations:release')
-    do
-        defines({ 'RELEASE' })
-        defines({ 'NDEBUG' })
-        optimize('On')
-    end
-
-    filter({ 'system:macosx', 'options:variant=runtime' })
-    do
-        buildoptions({
-            '-Wimplicit-float-conversion -fembed-bitcode -arch arm64 -arch x86_64 -isysroot '
-                .. (os.getenv('MACOS_SYSROOT') or ''),
-        })
-    end
-
-    filter({ 'system:macosx', 'configurations:release' })
-    do
-        buildoptions({ '-flto=full' })
-    end
-
-    filter({ 'system:ios' })
-    do
-        buildoptions({ '-flto=full' })
-    end
-
-    filter('system:windows')
-    do
-        architecture('x64')
-        defines({ '_USE_MATH_DEFINES' })
-    end
-
-    filter({ 'system:ios', 'options:variant=system' })
-    do
-        buildoptions({
-            '-mios-version-min=13.0 -fembed-bitcode -arch arm64 -isysroot '
-                .. (os.getenv('IOS_SYSROOT') or ''),
-        })
-    end
-
-    filter({ 'system:ios', 'options:variant=emulator' })
-    do
-        buildoptions({
-            '--target=arm64-apple-ios13.0.0-simulator',
-            '-mios-version-min=13.0 -arch arm64 -arch x86_64 -isysroot '
-                .. (os.getenv('IOS_SYSROOT') or ''),
-        })
-        targetdir('%{cfg.system}_sim/cache/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}_sim/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:ios', 'options:variant=xros' })
-    do
-        buildoptions({
-            '--target=arm64-apple-xros1.0',
-            '-fembed-bitcode -arch arm64 -isysroot '
-                .. (os.getenv('XROS_SYSROOT') or ''),
-        })
-        targetdir('xros/cache/bin/%{cfg.buildcfg}')
-        objdir('xros/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:ios', 'options:variant=xrsimulator' })
-    do
-        buildoptions({
-            '--target=arm64-apple-xros1.0-simulator',
-            '-arch arm64 -arch x86_64 -isysroot '
-                .. (os.getenv('XROS_SYSROOT') or ''),
-        })
-        targetdir('xrsimulator/cache/bin/%{cfg.buildcfg}')
-        objdir('xrsimulator/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:ios', 'options:variant=appletvos' })
-    do
-        buildoptions({
-            '--target=arm64-apple-tvos',
-            '-mappletvos-version-min=16.0',
-            '-fembed-bitcode -arch arm64 -isysroot '
-                .. (os.getenv('APPLETVOS_SYSROOT') or ''),
-        })
-        targetdir('appletvos/cache/bin/%{cfg.buildcfg}')
-        objdir('appletvos/cache/obj/%{cfg.buildcfg}')
-        defines({ 'RIVE_APPLETVOS' })
-    end
-
-    filter({ 'system:ios', 'options:variant=appletvsimulator' })
-    do
-        buildoptions({
-            '--target=arm64-apple-tvos-simulator',
-            '-mappletvsimulator-version-min=16.0',
-            '-arch arm64 -arch x86_64 -isysroot '
-                .. (os.getenv('APPLETVOS_SYSROOT') or ''),
-        })
-        targetdir('appletvsimulator/cache/bin/%{cfg.buildcfg}')
-        objdir('appletvsimulator/cache/obj/%{cfg.buildcfg}')
-        defines({ 'RIVE_APPLETVOS_SIMULATOR' })
-    end
-
-    filter({ 'system:android', 'configurations:release' })
-    do
-        buildoptions({ '-flto=full' })
-    end
-
-    -- Is there a way to pass 'arch' as a variable here?
-    filter({ 'system:android', 'options:arch=x86' })
-    do
-        targetdir('%{cfg.system}/cache/x86/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/x86/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:android', 'options:arch=x64' })
-    do
-        targetdir('%{cfg.system}/cache/x64/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/x64/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:android', 'options:arch=arm' })
-    do
-        targetdir('%{cfg.system}/cache/arm/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/arm/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:android', 'options:arch=arm64' })
-    do
-        targetdir('%{cfg.system}/cache/arm64/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/arm64/obj/%{cfg.buildcfg}')
-    end
-
-    filter('system:macosx or system:ios')
-    do
-        defines({ 'HAVE_CORETEXT' })
-        files({ harfbuzz .. '/src/hb-coretext-shape.cc', harfbuzz .. '/src/hb-coretext-font.cc' })
-    end
-end
diff --git a/dependencies/premake5_harfbuzz_v2.lua b/dependencies/premake5_harfbuzz_v2.lua
index 49ee68f..6945df5 100644
--- a/dependencies/premake5_harfbuzz_v2.lua
+++ b/dependencies/premake5_harfbuzz_v2.lua
@@ -1,7 +1,7 @@
 dofile('rive_build_config.lua')
 
 local dependency = require('dependency')
-harfbuzz = dependency.github('rive-app/harfbuzz', 'rive_10.1.0')
+harfbuzz = dependency.github('rive-app/harfbuzz', 'rive_13.1.1')
 
 newoption({
     trigger = 'no-harfbuzz-renames',
@@ -45,9 +45,10 @@
         harfbuzz .. '/src/hb-blob.cc',
         harfbuzz .. '/src/hb-blob.hh',
         harfbuzz .. '/src/hb-buffer-deserialize-json.hh',
-        harfbuzz .. '/src/hb-buffer-deserialize-text.hh',
-        harfbuzz .. '/src/hb-buffer-serialize.cc',
-        harfbuzz .. '/src/hb-buffer-verify.cc',
+        harfbuzz .. '/src/hb-buffer-deserialize-text-glyphs.hh',
+        harfbuzz .. '/src/hb-buffer-deserialize-text-unicode.hh',
+        -- hb-buffer-serialize.cc and hb-buffer-verify.cc removed:
+        -- already no-ops via HB_NO_BUFFER_SERIALIZE / HB_NO_BUFFER_VERIFY
         harfbuzz .. '/src/hb-buffer.cc',
         harfbuzz .. '/src/hb-buffer.hh',
         harfbuzz .. '/src/hb-cache.hh',
@@ -63,6 +64,7 @@
         harfbuzz .. '/src/hb-draw.cc',
         harfbuzz .. '/src/hb-draw.h',
         harfbuzz .. '/src/hb-draw.hh',
+        harfbuzz .. '/src/hb-face-builder.cc',
         harfbuzz .. '/src/hb-face.cc',
         harfbuzz .. '/src/hb-face.hh',
         harfbuzz .. '/src/hb-font.cc',
@@ -89,12 +91,6 @@
         harfbuzz .. '/src/hb-ot-cff2-table.cc',
         harfbuzz .. '/src/hb-ot-cff2-table.hh',
         harfbuzz .. '/src/hb-ot-cmap-table.hh',
-        harfbuzz .. '/src/hb-ot-color-cbdt-table.hh',
-        harfbuzz .. '/src/hb-ot-color-colr-table.hh',
-        harfbuzz .. '/src/hb-ot-color-colrv1-closure.hh',
-        harfbuzz .. '/src/hb-ot-color-cpal-table.hh',
-        harfbuzz .. '/src/hb-ot-color-sbix-table.hh',
-        harfbuzz .. '/src/hb-ot-color-svg-table.hh',
         harfbuzz .. '/src/hb-ot-color.cc',
         harfbuzz .. '/src/hb-ot-color.h',
         harfbuzz .. '/src/hb-ot-deprecated.h',
@@ -182,9 +178,10 @@
         harfbuzz .. '/src/hb-ot-var-mvar-table.hh',
         harfbuzz .. '/src/hb-ot-var.cc',
         harfbuzz .. '/src/hb-ot-vorg-table.hh',
-        harfbuzz .. '/src/hb-pool.hh',
+        harfbuzz .. '/src/hb-alloc-pool.hh',
+        harfbuzz .. '/src/hb-free-pool.hh',
         harfbuzz .. '/src/hb-priority-queue.hh',
-        harfbuzz .. '/src/hb-repacker.hh',
+        -- hb-repacker.hh removed: only used by subsetting
         harfbuzz .. '/src/hb-sanitize.hh',
         harfbuzz .. '/src/hb-serialize.hh',
         harfbuzz .. '/src/hb-set-digest.hh',
@@ -199,34 +196,30 @@
         harfbuzz .. '/src/hb-shaper.hh',
         harfbuzz .. '/src/hb-static.cc',
         harfbuzz .. '/src/hb-string-array.hh',
-        harfbuzz .. '/src/hb-subset-cff-common.cc',
-        harfbuzz .. '/src/hb-subset-cff-common.hh',
-        harfbuzz .. '/src/hb-subset-cff1.cc',
-        harfbuzz .. '/src/hb-subset-cff1.hh',
-        harfbuzz .. '/src/hb-subset-cff2.cc',
-        harfbuzz .. '/src/hb-subset-cff2.hh',
-        harfbuzz .. '/src/hb-subset-input.cc',
-        harfbuzz .. '/src/hb-subset-input.hh',
-        harfbuzz .. '/src/hb-subset-plan.cc',
-        harfbuzz .. '/src/hb-subset-plan.hh',
-        harfbuzz .. '/src/hb-subset-repacker.cc',
-        harfbuzz .. '/src/hb-subset-repacker.h',
-        harfbuzz .. '/src/hb-subset.cc',
-        harfbuzz .. '/src/hb-subset.hh',
+        -- Subsetting code removed: hb_subset_* never called by Rive (~228 KB)
+        -- hb-subset-cff-common.cc/.hh, hb-subset-cff2-to-cff1.cc,
+        -- hb-subset-instancer-iup.cc, hb-subset-instancer-solver.cc,
+        -- hb-subset-input.cc/.hh, hb-subset-plan.cc/.hh,
+        -- hb-subset-plan-layout.cc, hb-subset-plan-var.cc,
+        -- hb-subset-serialize.cc, hb-subset-table-*.cc,
+        -- hb-subset.cc/.hh
         harfbuzz .. '/src/hb-ucd-table.hh',
         harfbuzz .. '/src/hb-ucd.cc',
         harfbuzz .. '/src/hb-unicode-emoji-table.hh',
         harfbuzz .. '/src/hb-unicode.cc',
         harfbuzz .. '/src/hb-unicode.hh',
         harfbuzz .. '/src/hb-utf.hh',
+        harfbuzz .. '/src/hb-vector.cc',
         harfbuzz .. '/src/hb-vector.hh',
         harfbuzz .. '/src/hb.hh',
-        harfbuzz .. '/src/graph/gsubgpos-context.cc',
+        -- graph/gsubgpos-context.cc removed: only used by subsetting repacker
         harfbuzz .. '/src/hb-paint.cc',
+        harfbuzz .. '/src/hb-paint-bounded.cc',
         harfbuzz .. '/src/hb-paint-extents.cc',
         harfbuzz .. '/src/hb-outline.cc',
         harfbuzz .. '/src/hb-style.h',
         harfbuzz .. '/src/hb-style.cc',
+        harfbuzz .. '/src/OT/Var/VARC/VARC.cc',
     })
 
     warnings('Off')
@@ -234,29 +227,59 @@
     defines({
         'HB_ONLY_ONE_SHAPER', -- added this for Geotech Mac multi-module issue: https://github.com/rive-app/rive-cpp/issues/369
         'HAVE_OT',
-        'HB_NO_FALLBACK_SHAPE',
-        'HB_NO_WIN1256',
-        'HB_NO_EXTERN_HELPERS',
         'HB_DISABLE_DEPRECATED',
-        'HB_NO_COLOR',
-        'HB_NO_BITMAP',
+
+        -- Buffer debug/serialization features
         'HB_NO_BUFFER_SERIALIZE',
         'HB_NO_BUFFER_VERIFY',
         'HB_NO_BUFFER_MESSAGE',
-        'HB_NO_SETLOCALE',
+
+        -- Shaping features we don't use
+        'HB_NO_FALLBACK_SHAPE',
+        'HB_NO_WIN1256',
         'HB_NO_VERTICAL',
+        'HB_NO_MATH', -- Math typesetting — never called
+        'HB_NO_BASE', -- BASE table (baseline alignment) — never called
+        'HB_NO_OT_SHAPE_FRACTIONS', -- Fraction auto-detection
+        'HB_NO_OT_SHAPE_FALLBACK', -- Fallback for Arabic/Hebrew/Thai when fonts lack OT tables
+        'HB_NO_LEGACY', -- Legacy cmap subtables, old OT kern, layout blocklist
+
+        -- Layout trimming
         'HB_NO_LAYOUT_COLLECT_GLYPHS',
         'HB_NO_LAYOUT_RARELY_USED',
         'HB_NO_LAYOUT_UNUSED',
+
+        -- Font features we don't use
         'HB_NO_OT_FONT_GLYPH_NAMES',
-        'HB_NO_PAINT',
-        'HB_NO_MMAP',
+        'HB_NO_HINTING', -- TrueType hinting — Rive renders outlines directly
+        'HB_NO_NAME', -- hb_ot_name_* API — never called
         'HB_NO_META',
+        'HB_NO_METRICS', -- hb_ot_metrics_* API — never called
+        'HB_NO_SVG', -- SVG color glyphs — Rive uses COLR/CBDT, not SVG
+        'HB_NO_AVAR2', -- avar2 advanced axis mapping — very rare
+        'HB_NO_VAR_HVF', -- Variable font HVF — rare
+        'HB_NO_VAR_COMPOSITES', -- VARC table — experimental spec, no shipping fonts use it
+
+        -- System/environment
+        'HB_NO_EXTERN_HELPERS',
+        'HB_NO_SETLOCALE',
+        'HB_NO_MMAP',
+        'HB_NO_ATEXIT',
+        'HB_NO_ERRNO',
+        'HB_NO_GETENV',
+        'HB_NO_OPEN', -- hb_blob_create_from_file — Rive creates blobs from memory
+        'HB_NO_FACE_COLLECT_UNICODES',
+
+        -- Size optimization
+        'HB_OPTIMIZE_SIZE', -- Use smaller UCD lookup tables
+        'HB_NO_UCD_UNASSIGNED', -- Skip unassigned codepoint properties
+
+        -- 'HB_NO_PAINT', -- Needed for COLRv1 emoji support
     })
 
     filter('toolset:not msc')
     do
-        fatalwarnings { "All" }
+        fatalwarnings({ 'All' })
         buildoptions({
             '-Werror=format',
             '-Wimplicit-int-conversion',
@@ -281,13 +304,21 @@
         forceincludes({ 'rive_harfbuzz_renames.h' })
     end
 
-    filter({ 'options:harfbuzz_getenv_no_op', 'files:**/src/hb-common.cc or **/src/hb-shaper.cc', 'options:no-harfbuzz-renames'})
+    filter({
+        'options:harfbuzz_getenv_no_op',
+        'files:**/src/hb-common.cc or **/src/hb-shaper.cc',
+        'options:no-harfbuzz-renames',
+    })
     do
         includedirs({ './' })
-        forceincludes({ 'rive_harfbuzz_overrides.h'})
+        forceincludes({ 'rive_harfbuzz_overrides.h' })
     end
 
-    filter({ 'options:harfbuzz_getenv_no_op', 'files:**/src/hb-common.cc or **/src/hb-shaper.cc', 'options:not no-harfbuzz-renames'})
+    filter({
+        'options:harfbuzz_getenv_no_op',
+        'files:**/src/hb-common.cc or **/src/hb-shaper.cc',
+        'options:not no-harfbuzz-renames',
+    })
     do
         includedirs({ './' })
         forceincludes({ 'rive_harfbuzz_overrides.h', 'rive_harfbuzz_renames.h' })
@@ -296,6 +327,10 @@
     filter('system:macosx or system:ios')
     do
         defines({ 'HAVE_CORETEXT' })
-        files({ harfbuzz .. '/src/hb-coretext-shape.cc', harfbuzz .. '/src/hb-coretext-font.cc' })
+        files({
+            harfbuzz .. '/src/hb-coretext.cc',
+            harfbuzz .. '/src/hb-coretext-shape.cc',
+            harfbuzz .. '/src/hb-coretext-font.cc',
+        })
     end
 end
diff --git a/dependencies/premake5_miniaudio.lua b/dependencies/premake5_miniaudio.lua
deleted file mode 100644
index 6779bba..0000000
--- a/dependencies/premake5_miniaudio.lua
+++ /dev/null
@@ -1,2 +0,0 @@
-local dependency = require('dependency')
-miniaudio = dependency.github('rive-app/miniaudio', 'rive_changes_4')
diff --git a/dependencies/premake5_sheenbidi.lua b/dependencies/premake5_sheenbidi.lua
deleted file mode 100644
index 05797fe..0000000
--- a/dependencies/premake5_sheenbidi.lua
+++ /dev/null
@@ -1,186 +0,0 @@
-local dependency = require('dependency')
-sheenbidi = dependency.github('Tehreer/SheenBidi', 'v2.6')
-
-workspace('rive')
-configurations({ 'debug', 'release' })
-
-project('rive_sheenbidi')
-do
-    kind('StaticLib')
-    language('C')
-    targetdir('%{cfg.system}/cache/bin/%{cfg.buildcfg}/')
-    objdir('%{cfg.system}/cache/obj/%{cfg.buildcfg}/')
-    warnings('Off')
-
-    includedirs({ sheenbidi .. '/Headers' })
-
-    buildoptions({ '-Wall', '-ansi', '-pedantic' })
-
-    linkoptions({ '-r' })
-
-    filter('system:emscripten')
-    do
-        buildoptions({ '-pthread' })
-    end
-
-    filter('configurations:debug')
-    do
-        files({
-            sheenbidi .. '/Source/BidiChain.c',
-            sheenbidi .. '/Source/BidiTypeLookup.c',
-            sheenbidi .. '/Source/BracketQueue.c',
-            sheenbidi .. '/Source/GeneralCategoryLookup.c',
-            sheenbidi .. '/Source/IsolatingRun.c',
-            sheenbidi .. '/Source/LevelRun.c',
-            sheenbidi .. '/Source/PairingLookup.c',
-            sheenbidi .. '/Source/RunQueue.c',
-            sheenbidi .. '/Source/SBAlgorithm.c',
-            sheenbidi .. '/Source/SBBase.c',
-            sheenbidi .. '/Source/SBCodepointSequence.c',
-            sheenbidi .. '/Source/SBLine.c',
-            sheenbidi .. '/Source/SBLog.c',
-            sheenbidi .. '/Source/SBMirrorLocator.c',
-            sheenbidi .. '/Source/SBParagraph.c',
-            sheenbidi .. '/Source/SBScriptLocator.c',
-            sheenbidi .. '/Source/ScriptLookup.c',
-            sheenbidi .. '/Source/ScriptStack.c',
-            sheenbidi .. '/Source/StatusStack.c',
-        })
-    end
-    filter('configurations:release')
-    do
-        files({ sheenbidi .. '/Source/SheenBidi.c' })
-    end
-
-    filter('configurations:debug')
-    do
-        defines({ 'DEBUG' })
-        symbols('On')
-    end
-
-    filter('configurations:release')
-    do
-        buildoptions({ '-Oz' })
-        defines({ 'RELEASE', 'NDEBUG', 'SB_CONFIG_UNITY' })
-        optimize('On')
-    end
-
-    filter({ 'system:macosx', 'options:variant=runtime' })
-    do
-        buildoptions({
-            '-Wimplicit-float-conversion -fembed-bitcode -arch arm64 -arch x86_64 -isysroot '
-                .. (os.getenv('MACOS_SYSROOT') or ''),
-        })
-    end
-
-    filter({ 'system:macosx', 'configurations:release' })
-    do
-        buildoptions({ '-flto=full' })
-    end
-
-    filter({ 'system:ios' })
-    do
-        buildoptions({ '-flto=full' })
-    end
-
-    filter('system:windows')
-    do
-        architecture('x64')
-        defines({ '_USE_MATH_DEFINES' })
-    end
-
-    filter({ 'system:ios', 'options:variant=system' })
-    do
-        buildoptions({
-            '-mios-version-min=13.0 -fembed-bitcode -arch arm64 -isysroot '
-                .. (os.getenv('IOS_SYSROOT') or ''),
-        })
-    end
-
-    filter({ 'system:ios', 'options:variant=emulator' })
-    do
-        buildoptions({
-            '--target=arm64-apple-ios13.0.0-simulator',
-            '-mios-version-min=13.0 -arch arm64 -arch x86_64 -isysroot '
-                .. (os.getenv('IOS_SYSROOT') or ''),
-        })
-        targetdir('%{cfg.system}_sim/cache/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}_sim/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:ios', 'options:variant=xros' })
-    do
-        buildoptions({
-            '--target=arm64-apple-xros1.0',
-            '-fembed-bitcode -arch arm64 -isysroot '
-                .. (os.getenv('XROS_SYSROOT') or ''),
-        })
-        targetdir('xros/cache/bin/%{cfg.buildcfg}')
-        objdir('xros/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:ios', 'options:variant=xrsimulator' })
-    do
-        buildoptions({
-            '--target=arm64-apple-xros1.0-simulator',
-            '-arch arm64 -arch x86_64 -isysroot '
-                .. (os.getenv('XROS_SYSROOT') or ''),
-        })
-        targetdir('xrsimulator/cache/bin/%{cfg.buildcfg}')
-        objdir('xrsimulator/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:ios', 'options:variant=appletvos' })
-    do
-        buildoptions({
-            '--target=arm64-apple-tvos',
-            '-mappletvos-version-min=16.0',
-            '-fembed-bitcode -arch arm64 -isysroot '
-                .. (os.getenv('APPLETVOS_SYSROOT') or ''),
-        })
-        targetdir('appletvos/cache/bin/%{cfg.buildcfg}')
-        objdir('appletvos/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:ios', 'options:variant=appletvsimulator' })
-    do
-        buildoptions({
-            '--target=arm64-apple-tvos-simulator',
-            '-mappletvsimulator-version-min=16.0',
-            '-arch arm64 -arch x86_64 -isysroot '
-                .. (os.getenv('APPLETVOS_SYSROOT') or ''),
-        })
-        targetdir('appletvsimulator/cache/bin/%{cfg.buildcfg}')
-        objdir('appletvsimulator/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:android', 'configurations:release' })
-    do
-        buildoptions({ '-flto=full' })
-    end
-
-    -- Is there a way to pass 'arch' as a variable here?
-    filter({ 'system:android', 'options:arch=x86' })
-    do
-        targetdir('%{cfg.system}/cache/x86/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/x86/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:android', 'options:arch=x64' })
-    do
-        targetdir('%{cfg.system}/cache/x64/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/x64/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:android', 'options:arch=arm' })
-    do
-        targetdir('%{cfg.system}/cache/arm/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/arm/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:android', 'options:arch=arm64' })
-    do
-        targetdir('%{cfg.system}/cache/arm64/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/arm64/obj/%{cfg.buildcfg}')
-    end
-end
diff --git a/dependencies/premake5_yoga.lua b/dependencies/premake5_yoga.lua
deleted file mode 100644
index 756f4df..0000000
--- a/dependencies/premake5_yoga.lua
+++ /dev/null
@@ -1,187 +0,0 @@
-local dependency = require('dependency')
-yoga = dependency.github('rive-app/yoga', 'rive_changes_v2_0_1_2')
-
-workspace('rive')
-configurations({ 'debug', 'release' })
-
-project('rive_yoga')
-do
-    kind('StaticLib')
-    language('C++')
-    cppdialect('C++11')
-    targetdir('%{cfg.system}/cache/bin/%{cfg.buildcfg}/')
-    objdir('%{cfg.system}/cache/obj/%{cfg.buildcfg}/')
-    warnings('Off')
-
-    defines({ 'YOGA_EXPORT=' })
-
-    includedirs({ yoga })
-
-    files({
-        yoga .. '/yoga/Utils.cpp',
-        yoga .. '/yoga/YGConfig.cpp',
-        yoga .. '/yoga/YGLayout.cpp',
-        yoga .. '/yoga/YGEnums.cpp',
-        yoga .. '/yoga/YGNodePrint.cpp',
-        yoga .. '/yoga/YGNode.cpp',
-        yoga .. '/yoga/YGValue.cpp',
-        yoga .. '/yoga/YGStyle.cpp',
-        yoga .. '/yoga/Yoga.cpp',
-        yoga .. '/yoga/event/event.cpp',
-        yoga .. '/yoga/log.cpp',
-    })
-
-    includedirs({ './' })
-    forceincludes({ 'rive_yoga_renames.h' })
-
-    buildoptions({ '-Wall', '-pedantic' })
-
-    linkoptions({ '-r' })
-
-    filter('system:emscripten')
-    do
-        buildoptions({ '-pthread' })
-    end
-
-    filter('configurations:debug')
-    do
-        defines({ 'DEBUG' })
-        symbols('On')
-    end
-
-    filter('toolset:clang')
-    do
-        fatalwarnings { "All" }
-        buildoptions({
-            '-Werror=format',
-            '-Wimplicit-int-conversion',
-            '-Werror=vla',
-        })
-    end
-
-    filter('configurations:release')
-    do
-        buildoptions({ '-Oz' })
-        defines({ 'RELEASE', 'NDEBUG' })
-        optimize('On')
-    end
-
-    filter({ 'system:macosx', 'options:variant=runtime' })
-    do
-        buildoptions({
-            '-Wimplicit-float-conversion -fembed-bitcode -arch arm64 -arch x86_64 -isysroot'
-                .. (os.getenv('MACOS_SYSROOT') or ''),
-        })
-    end
-
-    filter({ 'system:macosx', 'configurations:release' })
-    do
-        buildoptions({ '-flto=full' })
-    end
-
-    filter({ 'system:ios' })
-    do
-        buildoptions({ '-flto=full' })
-    end
-
-    filter('system:windows')
-    do
-        architecture('x64')
-        defines({ '_USE_MATH_DEFINES' })
-    end
-
-    filter({ 'system:ios', 'options:variant=system' })
-    do
-        buildoptions({
-            '-mios-version-min=13.0 -fembed-bitcode -arch arm64 -isysroot '
-                .. (os.getenv('IOS_SYSROOT') or ''),
-        })
-    end
-
-    filter({ 'system:ios', 'options:variant=emulator' })
-    do
-        buildoptions({
-            '--target=arm64-apple-ios13.0.0-simulator',
-            '-mios-version-min=13.0 -arch arm64 -arch x86_64 -isysroot '
-                .. (os.getenv('IOS_SYSROOT') or ''),
-        })
-        targetdir('%{cfg.system}_sim/cache/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}_sim/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:ios', 'options:variant=xros' })
-    do
-        buildoptions({
-            '--target=arm64-apple-xros1.0',
-            '-fembed-bitcode -arch arm64 -isysroot '
-                .. (os.getenv('XROS_SYSROOT') or ''),
-        })
-        targetdir('xros/cache/bin/%{cfg.buildcfg}')
-        objdir('xros/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:ios', 'options:variant=xrsimulator' })
-    do
-        buildoptions({
-            '--target=arm64-apple-xros1.0-simulator',
-            '-arch arm64 -arch x86_64 -isysroot '
-                .. (os.getenv('XROS_SYSROOT') or ''),
-        })
-        targetdir('xrsimulator/cache/bin/%{cfg.buildcfg}')
-        objdir('xrsimulator/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:ios', 'options:variant=appletvos' })
-    do
-        buildoptions({
-            '--target=arm64-apple-tvos',
-            '-mappletvos-version-min=16.0',
-            '-fembed-bitcode -arch arm64 -isysroot '
-                .. (os.getenv('APPLETVOS_SYSROOT') or ''),
-        })
-        targetdir('appletvos/cache/bin/%{cfg.buildcfg}')
-        objdir('appletvos/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:ios', 'options:variant=appletvsimulator' })
-    do
-        buildoptions({
-            '--target=arm64-apple-tvos-simulator',
-            '-mappletvos-version-min=16.0',
-            '-arch arm64 -arch x86_64 -isysroot '
-                .. (os.getenv('APPLETVOS_SYSROOT') or ''),
-        })
-        targetdir('appletvsimulator/cache/bin/%{cfg.buildcfg}')
-        objdir('appletvsimulator/cache/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:android', 'configurations:release' })
-    do
-        buildoptions({ '-flto=full' })
-    end
-
-    -- Is there a way to pass 'arch' as a variable here?
-    filter({ 'system:android', 'options:arch=x86' })
-    do
-        targetdir('%{cfg.system}/cache/x86/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/x86/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:android', 'options:arch=x64' })
-    do
-        targetdir('%{cfg.system}/cache/x64/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/x64/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:android', 'options:arch=arm' })
-    do
-        targetdir('%{cfg.system}/cache/arm/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/arm/obj/%{cfg.buildcfg}')
-    end
-
-    filter({ 'system:android', 'options:arch=arm64' })
-    do
-        targetdir('%{cfg.system}/cache/arm64/bin/%{cfg.buildcfg}')
-        objdir('%{cfg.system}/cache/arm64/obj/%{cfg.buildcfg}')
-    end
-end
diff --git a/dependencies/rive_harfbuzz_renames.h b/dependencies/rive_harfbuzz_renames.h
index d4fa56f..0733862 100644
--- a/dependencies/rive_harfbuzz_renames.h
+++ b/dependencies/rive_harfbuzz_renames.h
@@ -1,528 +1,169 @@
 // clang-format off
 // hb_*
-#define hb_vector_t rive_hb_vector_t
-#define hb_hashmap_t rive_hb_hashmap_t
-#define hb_serialize_context_t rive_hb_serialize_context_t
-#define hb_array_t rive_hb_array_t
-#define hb_array rive_hb_array
-#define hb_barrier rive_hb_barrier
-#define hb_identity rive_hb_identity
-#define hb_ridentity rive_hb_ridentity
-#define hb_bit_storage rive_hb_bit_storage
-#define hb_object_fini rive_hb_object_fini
-#define hb_object_init rive_hb_object_init
-#define hb_unsigned_mul_overflows rive_hb_unsigned_mul_overflows
-#define hb_user_data_array_t rive_hb_user_data_array_t
-#define hb_get rive_hb_get
-#define hb_has rive_hb_has
-#define hb_map rive_hb_map
-#define hb_max rive_hb_max
-#define hb_hash rive_hb_hash
-#define hb_iter rive_hb_iter
-#define hb_swap rive_hb_swap
-#define hb_deref rive_hb_deref
-#define hb_concat rive_hb_concat
-#define hb_filter rive_hb_filter
-#define hb_invoke rive_hb_invoke
-#define hb_memset rive_hb_memset
-#define hb_mutex_t rive_hb_mutex_t
-#define hb_priority rive_hb_priority
-#define hb_map_iter_t rive_hb_map_iter_t
-#define hb_atomic_int_t rive_hb_atomic_int_t
-#define hb_atomic_ptr_t rive_hb_atomic_ptr_t
-#define hb_concat_iter_t rive_hb_concat_iter_t
-#define hb_filter_iter_t rive_hb_filter_iter_t
-#define hb_lockable_set_t rive_hb_lockable_set_t
-#define hb_object_header_t rive_hb_object_header_t
-#define hb_reference_count_t rive_hb_reference_count_t
-#define hb_reference_wrapper rive_hb_reference_wrapper
-#define hb_map_iter_factory_t rive_hb_map_iter_factory_t
-#define hb_filter_iter_factory_t rive_hb_filter_iter_factory_t
-#define hb_iter_t rive_hb_iter_t
-#define hb_iter_fallback_mixin_t rive_hb_iter_fallback_mixin_t
-#define hb_match_reference rive_hb_match_reference
-#define hb_sorted_array_t rive_hb_sorted_array_t
-#define hb_sorted_array rive_hb_sorted_array
-#define hb_aat_layout_track rive_hb_aat_layout_track
-#define hb_font_t rive_hb_font_t
-#define hb_buffer_t rive_hb_buffer_t
-#define hb_aat_layout_position rive_hb_aat_layout_position
-#define hb_aat_layout_substitute rive_hb_aat_layout_substitute
-#define hb_feature_t rive_hb_feature_t
-#define hb_aat_layout_compile_map rive_hb_aat_layout_compile_map
-#define hb_aat_map_t rive_hb_aat_map_t
-#define hb_aat_layout_find_feature_mapping rive_hb_aat_layout_find_feature_mapping
-#define hb_aat_layout_remove_deleted_glyphs rive_hb_aat_layout_remove_deleted_glyphs
-#define hb_aat_layout_zero_width_deleted_glyphs rive_hb_aat_layout_zero_width_deleted_glyphs
-#define hb_aat_map_builder_t rive_hb_aat_map_builder_t
-#define hb_aat_feature_mapping_t rive_hb_aat_feature_mapping_t
-#define hb_bsearch_impl rive_hb_bsearch_impl
-#define hb_aat_layout_feature_type_t rive_hb_aat_layout_feature_type_t
-#define hb_glyph_info_t rive_hb_glyph_info_t
-#define hb_set_digest_combiner_t rive_hb_set_digest_combiner_t
-#define hb_set_digest_bits_pattern_t rive_hb_set_digest_bits_pattern_t
-#define hb_aat_layout_feature_selector_info_t rive_hb_aat_layout_feature_selector_info_t
-#define hb_min rive_hb_min
-#define hb_none rive_hb_none
-#define hb_sink rive_hb_sink
-#define hb_clamp rive_hb_clamp
-#define hb_match rive_hb_match
-#define hb_memcpy rive_hb_memcpy
-#define hb_cache_t rive_hb_cache_t
-#define hb_blob_ptr_t rive_hb_blob_ptr_t
-#define hb_no_trace_t rive_hb_no_trace_t
-#define hb_lazy_loader_t rive_hb_lazy_loader_t
-#define hb_face_lazy_loader_t rive_hb_face_lazy_loader_t
-#define hb_face_t rive_hb_face_t
-#define hb_table_lazy_loader_t rive_hb_table_lazy_loader_t
-#define hb_blob_t rive_hb_blob_t
-#define glyf_accelerator_t rive_glyf_accelerator_t
 #define OT rive_OT
-#define hb_nonnull_ptr_t rive_hb_nonnull_ptr_t
-#define hb_atomic_short_t rive_hb_atomic_short_t
-#define hb_segment_properties_t rive_hb_segment_properties_t
-#define hb_dispatch_context_t rive_hb_dispatch_context_t
-#define hb_sanitize_context_t rive_hb_sanitize_context_t
-#define hb_sanitize_with_object_t rive_hb_sanitize_with_object_t
-#define hb_direction_t rive_hb_direction_t
-#define hb_sink_t rive_hb_sink_t
-#define hb_data_wrapper_t rive_hb_data_wrapper_t
-#define hb_not_found_t rive_hb_not_found_t
-#define hb_glyph_position_t rive_hb_glyph_position_t
-#define hb_buffer_flags_t rive_hb_buffer_flags_t
-#define hb_buffer_scratch_flags_t rive_hb_buffer_scratch_flags_t
-#define hb_glyph_flags_t rive_hb_glyph_flags_t
-#define hb_unicode_props_flags_t rive_hb_unicode_props_flags_t
-#define hb_equal rive_hb_equal
-#define hb_qsort rive_hb_qsort
-#define hb_object_trace rive_hb_object_trace
-#define hb_object_create rive_hb_object_create
-#define hb_object_destroy rive_hb_object_destroy
-#define hb_object_is_valid rive_hb_object_is_valid
-#define hb_object_reference rive_hb_object_reference
-#define hb_object_is_immutable rive_hb_object_is_immutable
-#define hb_object_get_user_data rive_hb_object_get_user_data
-#define hb_user_data_key_t rive_hb_user_data_key_t
-#define hb_object_set_user_data rive_hb_object_set_user_data
-#define hb_object_make_immutable rive_hb_object_make_immutable
-#define hb_parse_int rive_hb_parse_int
-#define hb_parse_uint rive_hb_parse_uint
-#define hb_buffer_serialize_format_t rive_hb_buffer_serialize_format_t
-#define hb_buffer_serialize_flags_t rive_hb_buffer_serialize_flags_t
-#define hb_in_range rive_hb_in_range
-#define hb_stable_sort rive_hb_stable_sort
-#define hb_buffer_add_utf rive_hb_buffer_add_utf
-#define hb_latin1_t rive_hb_latin1_t
-#define hb_utf16_xe_t rive_hb_utf16_xe_t
-#define hb_utf32_xe_t rive_hb_utf32_xe_t
-#define hb_utf8_t rive_hb_utf8_t
-#define hb_unicode_funcs_t rive_hb_unicode_funcs_t
-#define hb_buffer_diff_flags_t rive_hb_buffer_diff_flags_t
-#define hb_parse_double rive_hb_parse_double
-#define hb_variation_t rive_hb_variation_t
-#define hb_language_item_t rive_hb_language_item_t
-#define hb_language_impl_t rive_hb_language_impl_t
-#define hb_language_get_default rive_hb_language_get_default
-#define hb_draw_funcs_t rive_hb_draw_funcs_t
-#define hb_draw_line_to_nil rive_hb_draw_line_to_nil
-#define hb_draw_state_t rive_hb_draw_state_t
-#define hb_draw_move_to_nil rive_hb_draw_move_to_nil
-#define hb_draw_cubic_to_nil rive_hb_draw_cubic_to_nil
-#define hb_draw_close_path_nil rive_hb_draw_close_path_nil
-#define hb_draw_quadratic_to_nil rive_hb_draw_quadratic_to_nil
-#define hb_fill rive_hb_fill
-#define hb_bsearch rive_hb_bsearch
-#define hb_bit_set_t rive_hb_bit_set_t
-#define hb_bit_page_t rive_hb_bit_page_t
-#define hb_ot_face_t rive_hb_ot_face_t
-#define hb_sparseset_t rive_hb_sparseset_t
-#define hb_shaper_lazy_loader_t rive_hb_shaper_lazy_loader_t
-#define hb_ot_face_data_t rive_hb_ot_face_data_t
-#define hb_vector_size_t rive_hb_vector_size_t
-#define hb_bit_set_invertible_t rive_hb_bit_set_invertible_t
-#define hb_shaper_object_dataset_t rive_hb_shaper_object_dataset_t
-#define hb_set_t rive_hb_set_t
-#define hb_map_t rive_hb_map_t
-#define hb_font_funcs_t rive_hb_font_funcs_t
-#define hb_trampoline_t rive_hb_trampoline_t
-#define hb_codepoint_parse rive_hb_codepoint_parse
-#define hb_font_draw_glyph_nil rive_hb_font_draw_glyph_nil
-#define hb_draw_line_to_default rive_hb_draw_line_to_default
-#define hb_draw_move_to_default rive_hb_draw_move_to_default
-#define hb_font_paint_glyph_nil rive_hb_font_paint_glyph_nil
-#define hb_paint_funcs_t rive_hb_paint_funcs_t
-#define hb_draw_cubic_to_default rive_hb_draw_cubic_to_default
-#define hb_draw_close_path_default rive_hb_draw_close_path_default
-#define hb_font_draw_glyph_default rive_hb_font_draw_glyph_default
-#define hb_font_get_glyph_name_nil rive_hb_font_get_glyph_name_nil
-#define hb_font_paint_glyph_default rive_hb_font_paint_glyph_default
-#define hb_draw_quadratic_to_default rive_hb_draw_quadratic_to_default
-#define hb_font_get_glyph_extents_nil rive_hb_font_get_glyph_extents_nil
-#define hb_glyph_extents_t rive_hb_glyph_extents_t
-#define hb_font_get_nominal_glyph_nil rive_hb_font_get_nominal_glyph_nil
-#define hb_font_get_font_h_extents_nil rive_hb_font_get_font_h_extents_nil
-#define hb_font_extents_t rive_hb_font_extents_t
-#define hb_font_get_font_v_extents_nil rive_hb_font_get_font_v_extents_nil
-#define hb_font_get_glyph_h_origin_nil rive_hb_font_get_glyph_h_origin_nil
-#define hb_font_get_glyph_name_default rive_hb_font_get_glyph_name_default
-#define hb_font_get_glyph_v_origin_nil rive_hb_font_get_glyph_v_origin_nil
-#define hb_font_get_glyph_from_name_nil rive_hb_font_get_glyph_from_name_nil
-#define hb_font_get_glyph_h_advance_nil rive_hb_font_get_glyph_h_advance_nil
-#define hb_font_get_glyph_h_kerning_nil rive_hb_font_get_glyph_h_kerning_nil
-#define hb_font_get_glyph_v_advance_nil rive_hb_font_get_glyph_v_advance_nil
-#define hb_font_get_glyph_v_kerning_nil rive_hb_font_get_glyph_v_kerning_nil
-#define hb_font_get_variation_glyph_nil rive_hb_font_get_variation_glyph_nil
-#define hb_font_get_glyph_extents_default rive_hb_font_get_glyph_extents_default
-#define hb_font_get_nominal_glyph_default rive_hb_font_get_nominal_glyph_default
-#define hb_font_get_font_h_extents_default rive_hb_font_get_font_h_extents_default
-#define hb_font_get_font_v_extents_default rive_hb_font_get_font_v_extents_default
-#define hb_font_get_glyph_h_origin_default rive_hb_font_get_glyph_h_origin_default
-#define hb_font_get_glyph_v_origin_default rive_hb_font_get_glyph_v_origin_default
-#define hb_font_get_nominal_glyphs_default rive_hb_font_get_nominal_glyphs_default
-#define hb_font_get_glyph_contour_point_nil rive_hb_font_get_glyph_contour_point_nil
-#define hb_font_get_glyph_from_name_default rive_hb_font_get_glyph_from_name_default
-#define hb_font_get_glyph_h_advance_default rive_hb_font_get_glyph_h_advance_default
-#define hb_font_get_glyph_h_kerning_default rive_hb_font_get_glyph_h_kerning_default
-#define hb_font_get_glyph_v_advance_default rive_hb_font_get_glyph_v_advance_default
-#define hb_font_get_glyph_v_kerning_default rive_hb_font_get_glyph_v_kerning_default
-#define hb_font_get_variation_glyph_default rive_hb_font_get_variation_glyph_default
-#define hb_font_get_glyph_h_advances_default rive_hb_font_get_glyph_h_advances_default
-#define hb_font_get_glyph_v_advances_default rive_hb_font_get_glyph_v_advances_default
-#define hb_font_get_nominal_glyph_trampoline rive_hb_font_get_nominal_glyph_trampoline
-#define hb_font_get_variation_glyph_trampoline rive_hb_font_get_variation_glyph_trampoline
-#define hb_font_get_glyph_contour_point_default rive_hb_font_get_glyph_contour_point_default
-#define hb_ot_font_data_t rive_hb_ot_font_data_t
-#define hb_copy rive_hb_copy
-#define hb_reduce rive_hb_reduce
-#define hb_reduce_t rive_hb_reduce_t
-#define hb_pair_t rive_hb_pair_t
-#define hb_draw_session_t rive_hb_draw_session_t
-#define hb_ot_color_layer_t rive_hb_ot_color_layer_t
-#define hb_paint_extents_get_funcs rive_hb_paint_extents_get_funcs
-#define hb_ot_metrics_tag_t rive_hb_ot_metrics_tag_t
-#define hb_outline_recording_pen_get_funcs rive_hb_outline_recording_pen_get_funcs
-#define hb_ot_draw_glyph rive_hb_ot_draw_glyph
-#define hb_ot_paint_glyph rive_hb_ot_paint_glyph
-#define hb_ot_get_glyph_name rive_hb_ot_get_glyph_name
-#define hb_ot_get_glyph_extents rive_hb_ot_get_glyph_extents
-#define hb_ot_get_nominal_glyph rive_hb_ot_get_nominal_glyph
-#define hb_ot_get_font_h_extents rive_hb_ot_get_font_h_extents
-#define hb_ot_get_font_v_extents rive_hb_ot_get_font_v_extents
-#define hb_ot_get_glyph_v_origin rive_hb_ot_get_glyph_v_origin
-#define hb_ot_get_nominal_glyphs rive_hb_ot_get_nominal_glyphs
-#define hb_ot_get_glyph_from_name rive_hb_ot_get_glyph_from_name
-#define hb_ot_get_variation_glyph rive_hb_ot_get_variation_glyph
-#define hb_ot_get_glyph_h_advances rive_hb_ot_get_glyph_h_advances
-#define hb_ot_get_glyph_v_advances rive_hb_ot_get_glyph_v_advances
-#define hb_ot_font_cmap_cache_user_data_key rive_hb_ot_font_cmap_cache_user_data_key
-#define hb_bounds_t rive_hb_bounds_t
-#define hb_transform_t rive_hb_transform_t
-#define hb_memcmp rive_hb_memcmp
-#define hb_extents_t rive_hb_extents_t
-#define hb_outline_t rive_hb_outline_t
-#define hb_empty_t rive_hb_empty_t
-#define hb_ot_font_funcs_lazy_loader_t rive_hb_ot_font_funcs_lazy_loader_t
-#define hb_color_line_t rive_hb_color_line_t
-#define hb_paint_composite_mode_t rive_hb_paint_composite_mode_t
-#define hb_paint_extents_context_t rive_hb_paint_extents_context_t
-#define hb_font_funcs_lazy_loader_t rive_hb_font_funcs_lazy_loader_t
-#define hb_color_stop_t rive_hb_color_stop_t
-#define hb_partial rive_hb_partial
-#define hb_ot_layout_kern rive_hb_ot_layout_kern
-#define hb_ot_layout_has_kerning rive_hb_ot_layout_has_kerning
-#define hb_ot_layout_position_start rive_hb_ot_layout_position_start
-#define hb_ot_layout_substitute_start rive_hb_ot_layout_substitute_start
-#define hb_ot_layout_has_cross_kerning rive_hb_ot_layout_has_cross_kerning
-#define hb_ot_layout_substitute_lookup rive_hb_ot_layout_substitute_lookup
-#define hb_ot_layout_table_find_feature rive_hb_ot_layout_table_find_feature
-#define hb_ot_layout_has_machine_kerning rive_hb_ot_layout_has_machine_kerning
-#define hb_ot_layout_position_finish_offsets rive_hb_ot_layout_position_finish_offsets
-#define hb_ot_layout_position_finish_advances rive_hb_ot_layout_position_finish_advances
-#define hb_popcount rive_hb_popcount
-#define hb_enumerate rive_hb_enumerate
-#define hb_bitwise_gt rive_hb_bitwise_gt
-#define hb_bitwise_lt rive_hb_bitwise_lt
-#define hb_bitwise_or rive_hb_bitwise_or
-#define hb_bitwise_and rive_hb_bitwise_and
-#define hb_bitwise_neg rive_hb_bitwise_neg
-#define hb_unicode_general_category_t rive_hb_unicode_general_category_t
-#define hb_add rive_hb_add
-#define hb_all rive_hb_all
-#define hb_any rive_hb_any
-#define hb_ctz rive_hb_ctz
-#define hb_zip rive_hb_zip
-#define hb_iota rive_hb_iota
-#define hb_apply rive_hb_apply
-#define hb_first rive_hb_first
-#define hb_range rive_hb_range
-#define hb_second rive_hb_second
-#define hb_apply_t rive_hb_apply_t
-#define hb_partial_t rive_hb_partial_t
-#define hb_range_iter_t rive_hb_range_iter_t
-#define hb_zip_iter_t rive_hb_zip_iter_t
-#define hb_iota_iter_t rive_hb_iota_iter_t
-#define hb_collect_features_context_t rive_hb_collect_features_context_t
-#define hb_position_single_dispatch_t rive_hb_position_single_dispatch_t
-#define hb_get_glyph_alternates_dispatch_t rive_hb_get_glyph_alternates_dispatch_t
-#define hb_ot_map_t rive_hb_ot_map_t
-#define hb_ot_shape_plan_t rive_hb_ot_shape_plan_t
-#define hb_ot_map_builder_t rive_hb_ot_map_builder_t
-#define hb_ot_map_feature_flags_t rive_hb_ot_map_feature_flags_t
-#define hb_ot_shape_plan_key_t rive_hb_ot_shape_plan_key_t
-#define hb_ot_math_glyph_part_t rive_hb_ot_math_glyph_part_t
-#define hb_ot_math_glyph_variant_t rive_hb_ot_math_glyph_variant_t
-#define hb_ot_math_kern_t rive_hb_ot_math_kern_t
-#define hb_ot_math_kern_entry_t rive_hb_ot_math_kern_entry_t
-#define hb_ot_meta_tag_t rive_hb_ot_meta_tag_t
-#define hb_ot_name_entry_t rive_hb_ot_name_entry_t
-#define hb_ot_name_get_utf rive_hb_ot_name_get_utf
-#define hb_ascii_t rive_hb_ascii_t
-#define hb_ot_shape_fallback_kern_driver_t rive_hb_ot_shape_fallback_kern_driver_t
-#define hb_in_ranges rive_hb_in_ranges
-#define hb_ot_position rive_hb_ot_position
-#define hb_form_clusters rive_hb_form_clusters
-#define hb_vert_char_for rive_hb_vert_char_for
-#define hb_ot_rotate_chars rive_hb_ot_rotate_chars
-#define hb_propagate_flags rive_hb_propagate_flags
-#define hb_ot_position_plan rive_hb_ot_position_plan
-#define hb_ot_shape_internal rive_hb_ot_shape_internal
-#define hb_ot_substitute_pre rive_hb_ot_substitute_pre
-#define hb_set_unicode_props rive_hb_set_unicode_props
-#define hb_ot_map_glyphs_fast rive_hb_ot_map_glyphs_fast
-#define hb_ot_substitute_plan rive_hb_ot_substitute_plan
-#define hb_ot_substitute_post rive_hb_ot_substitute_post
-#define hb_ot_position_default rive_hb_ot_position_default
-#define hb_insert_dotted_circle rive_hb_insert_dotted_circle
-#define hb_ot_shape_setup_masks rive_hb_ot_shape_setup_masks
-#define hb_ot_shaper_categorize rive_hb_ot_shaper_categorize
-#define hb_ot_substitute_default rive_hb_ot_substitute_default
-#define hb_ensure_native_direction rive_hb_ensure_native_direction
-#define hb_synthesize_glyph_classes rive_hb_synthesize_glyph_classes
-#define hb_ot_shape_collect_features rive_hb_ot_shape_collect_features
-#define hb_ot_shape_initialize_masks rive_hb_ot_shape_initialize_masks
-#define hb_ot_hide_default_ignorables rive_hb_ot_hide_default_ignorables
-#define hb_ot_shape_setup_masks_fraction rive_hb_ot_shape_setup_masks_fraction
-#define hb_ot_zero_width_default_ignorables rive_hb_ot_zero_width_default_ignorables
-#define hb_shape_plan_key_t rive_hb_shape_plan_key_t
-#define hb_ot_shape_planner_t rive_hb_ot_shape_planner_t
-#define hb_script_t rive_hb_script_t
-#define hb_map_retains_sorting rive_hb_map_retains_sorting
-#define hb_pool_t rive_hb_pool_t
-#define hb_len rive_hb_len
-#define hb_serialize_error_t rive_hb_serialize_error_t
-#define hb_indic_get_categories rive_hb_indic_get_categories
-#define hb_syllabic_clear_var rive_hb_syllabic_clear_var
-#define hb_syllabic_insert_dotted_circles rive_hb_syllabic_insert_dotted_circles
-#define hb_options rive_hb_options
-#define hb_options_initv rive_hb_options_initv
-#define minus_1 rive_minus_1
-#define hb_aat_apply_context_t rive_hb_aat_apply_context_t
-#define _hb_unicode_is_emoji_Extended_Pictographic rive__hb_unicode_is_emoji_Extended_Pictographic
-#define endchar_str rive_endchar_str
+#define _hb_CrapPool rive__hb_CrapPool
+#define _hb_NullPool rive__hb_NullPool
+#define _hb_Null_AAT_Lookup rive__hb_Null_AAT_Lookup
+#define _hb_Null_AAT_SettingName rive__hb_Null_AAT_SettingName
+#define _hb_Null_OT_ClipRecord rive__hb_Null_OT_ClipRecord
+#define _hb_Null_OT_CmapSubtableLongGroup rive__hb_Null_OT_CmapSubtableLongGroup
+#define _hb_Null_OT_Index rive__hb_Null_OT_Index
+#define _hb_Null_OT_LangSys rive__hb_Null_OT_LangSys
+#define _hb_Null_OT_RangeRecord rive__hb_Null_OT_RangeRecord
+#define _hb_Null_OT_VarIdx rive__hb_Null_OT_VarIdx
+#define _hb_Null_hb_buffer_t rive__hb_Null_hb_buffer_t
+#define _hb_Null_hb_draw_funcs_t rive__hb_Null_hb_draw_funcs_t
+#define _hb_Null_hb_face_t rive__hb_Null_hb_face_t
+#define _hb_Null_hb_font_funcs_t rive__hb_Null_hb_font_funcs_t
+#define _hb_Null_hb_font_t rive__hb_Null_hb_font_t
+#define _hb_Null_hb_paint_funcs_t rive__hb_Null_hb_paint_funcs_t
+#define _hb_Null_hb_unicode_funcs_t rive__hb_Null_hb_unicode_funcs_t
+#define _hb_coretext_shape rive__hb_coretext_shape
+#define _hb_coretext_shaper_face_data_create rive__hb_coretext_shaper_face_data_create
+#define _hb_coretext_shaper_face_data_destroy rive__hb_coretext_shaper_face_data_destroy
+#define _hb_coretext_shaper_font_data_create rive__hb_coretext_shaper_font_data_create
+#define _hb_coretext_shaper_font_data_destroy rive__hb_coretext_shaper_font_data_destroy
+#define _hb_modified_combining_class rive__hb_modified_combining_class
 #define _hb_ot_name_language_for_mac_code rive__hb_ot_name_language_for_mac_code
 #define _hb_ot_name_language_for_ms_code rive__hb_ot_name_language_for_ms_code
-#define hb_indic_would_substitute_feature_t rive_hb_indic_would_substitute_feature_t
-#define hb_ot_layout_glyph_props_flags_t rive_hb_ot_layout_glyph_props_flags_t
-#define hb_use_u16 rive_hb_use_u16
-#define lookup_expert_subset_charset_for_glyph rive_lookup_expert_subset_charset_for_glyph
-#define lookup_expert_charset_for_glyph rive_lookup_expert_charset_for_glyph
-#define _hb_options_init rive__hb_options_init
-#define hb_use_get_category rive_hb_use_get_category
-#define hb_use_b4 rive_hb_use_b4
-#define hb_use_u8 rive_hb_use_u8
-#define hb_ot_new_tag_to_script rive_hb_ot_new_tag_to_script
-#define hb_ot_old_tag_to_script rive_hb_ot_old_tag_to_script
-#define hb_ot_tags_from_language rive_hb_ot_tags_from_language
-#define hb_ot_new_tag_from_script rive_hb_ot_new_tag_from_script
-#define hb_ot_old_tag_from_script rive_hb_ot_old_tag_from_script
-#define hb_ot_all_tags_from_script rive_hb_ot_all_tags_from_script
-#define hb_ot_ambiguous_tag_to_language rive_hb_ot_ambiguous_tag_to_language
-#define hb_ot_tags_from_complex_language rive_hb_ot_tags_from_complex_language
-#define hb_ot_var_axis_info_t rive_hb_ot_var_axis_info_t
-#define hb_ot_var_axis_t rive_hb_ot_var_axis_t
-#define hb_outline_recording_pen_line_to rive_hb_outline_recording_pen_line_to
-#define hb_outline_recording_pen_move_to rive_hb_outline_recording_pen_move_to
-#define hb_outline_recording_pen_cubic_to rive_hb_outline_recording_pen_cubic_to
-#define hb_outline_recording_pen_close_path rive_hb_outline_recording_pen_close_path
-#define hb_outline_recording_pen_quadratic_to rive_hb_outline_recording_pen_quadratic_to
-#define hb_outline_point_t rive_hb_outline_point_t
-#define hb_outline_recording_pen_funcs_lazy_loader_t rive_hb_outline_recording_pen_funcs_lazy_loader_t
-#define hb_outline_vector_t rive_hb_outline_vector_t
-#define hb_draw_funcs_lazy_loader_t rive_hb_draw_funcs_lazy_loader_t
-#define hb_draw_extents_line_to rive_hb_draw_extents_line_to
-#define hb_draw_extents_move_to rive_hb_draw_extents_move_to
-#define hb_draw_extents_cubic_to rive_hb_draw_extents_cubic_to
-#define hb_draw_extents_get_funcs rive_hb_draw_extents_get_funcs
-#define hb_paint_extents_pop_clip rive_hb_paint_extents_pop_clip
-#define hb_paint_extents_pop_group rive_hb_paint_extents_pop_group
-#define hb_paint_extents_push_group rive_hb_paint_extents_push_group
-#define hb_draw_extents_quadratic_to rive_hb_draw_extents_quadratic_to
-#define hb_paint_extents_paint_color rive_hb_paint_extents_paint_color
-#define hb_paint_extents_paint_image rive_hb_paint_extents_paint_image
-#define hb_paint_extents_pop_transform rive_hb_paint_extents_pop_transform
-#define hb_paint_extents_push_transform rive_hb_paint_extents_push_transform
-#define hb_paint_extents_push_clip_glyph rive_hb_paint_extents_push_clip_glyph
-#define hb_paint_extents_push_clip_rectangle rive_hb_paint_extents_push_clip_rectangle
-#define hb_paint_extents_paint_sweep_gradient rive_hb_paint_extents_paint_sweep_gradient
-#define hb_paint_extents_paint_linear_gradient rive_hb_paint_extents_paint_linear_gradient
-#define hb_paint_extents_paint_radial_gradient rive_hb_paint_extents_paint_radial_gradient
-#define hb_draw_extents_funcs_lazy_loader_t rive_hb_draw_extents_funcs_lazy_loader_t
-#define hb_paint_extents_funcs_lazy_loader_t rive_hb_paint_extents_funcs_lazy_loader_t
-#define hb_paint_funcs_lazy_loader_t rive_hb_paint_funcs_lazy_loader_t
-#define hb_paint_color_nil rive_hb_paint_color_nil
-#define hb_paint_image_nil rive_hb_paint_image_nil
-#define hb_paint_pop_clip_nil rive_hb_paint_pop_clip_nil
-#define hb_paint_pop_group_nil rive_hb_paint_pop_group_nil
-#define hb_paint_push_group_nil rive_hb_paint_push_group_nil
-#define hb_paint_color_glyph_nil rive_hb_paint_color_glyph_nil
-#define hb_paint_pop_transform_nil rive_hb_paint_pop_transform_nil
-#define hb_paint_push_transform_nil rive_hb_paint_push_transform_nil
-#define hb_paint_sweep_gradient_nil rive_hb_paint_sweep_gradient_nil
-#define hb_paint_linear_gradient_nil rive_hb_paint_linear_gradient_nil
-#define hb_paint_push_clip_glyph_nil rive_hb_paint_push_clip_glyph_nil
-#define hb_paint_radial_gradient_nil rive_hb_paint_radial_gradient_nil
-#define hb_paint_push_clip_rectangle_nil rive_hb_paint_push_clip_rectangle_nil
-#define hb_paint_custom_palette_color_nil rive_hb_paint_custom_palette_color_nil
-#define hb_bitwise_xor rive_hb_bitwise_xor
-#define hb_shape_plan_t rive_hb_shape_plan_t
-#define hb_shaper_list_lazy_loader_t rive_hb_shaper_list_lazy_loader_t
-#define hb_shapers_lazy_loader_t rive_hb_shapers_lazy_loader_t
-#define hb_shaper_entry_t rive_hb_shaper_entry_t
-#define hb_ot_language_map_t rive_hb_ot_language_map_t
-#define hb_serialize_cff_fdselect rive_hb_serialize_cff_fdselect
-#define hb_plan_subset_cff_fdselect rive_hb_plan_subset_cff_fdselect
-#define hb_inc_bimap_t rive_hb_inc_bimap_t
-#define hb_subset_plan_t rive_hb_subset_plan_t
-#define hb_subset_input_t rive_hb_subset_input_t
-#define hb_subset_flags_t rive_hb_subset_flags_t
-#define hb_bool rive_hb_bool
-#define hb_pair rive_hb_pair
-#define hb_multimap_t rive_hb_multimap_t
-#define hb_subset_accelerator_t rive_hb_subset_accelerator_t
-#define hb_lock_t rive_hb_lock_t
-#define hb_repeat_iter_t rive_hb_repeat_iter_t
-#define hb_resolve_overflows rive_hb_resolve_overflows
-#define hb_resolve_graph_overflows rive_hb_resolve_graph_overflows
-#define hb_subset_context_t rive_hb_subset_context_t
-#define hb_ceil_to_4 rive_hb_ceil_to_4
-#define hb_take rive_hb_take
-#define hb_drain rive_hb_drain
-#define hb_repeat rive_hb_repeat
-#define hb_priority_queue_t rive_hb_priority_queue_t
-#define hb_ucd_script rive_hb_ucd_script
-#define hb_ucd_compose rive_hb_ucd_compose
-#define hb_ucd_decompose rive_hb_ucd_decompose
-#define hb_ucd_mirroring rive_hb_ucd_mirroring
-#define hb_ucd_combining_class rive_hb_ucd_combining_class
-#define hb_ucd_general_category rive_hb_ucd_general_category
-#define hb_ucd_unicode_funcs_lazy_loader_t rive_hb_ucd_unicode_funcs_lazy_loader_t
-#define hb_unicode_funcs_lazy_loader_t rive_hb_unicode_funcs_lazy_loader_t
-#define hb_unicode_script_nil rive_hb_unicode_script_nil
-#define hb_unicode_compose_nil rive_hb_unicode_compose_nil
-#define hb_unicode_decompose_nil rive_hb_unicode_decompose_nil
-#define hb_unicode_mirroring_nil rive_hb_unicode_mirroring_nil
-#define hb_unicode_combining_class_nil rive_hb_unicode_combining_class_nil
-#define hb_unicode_eastasian_width_nil rive_hb_unicode_eastasian_width_nil
-#define hb_unicode_general_category_nil rive_hb_unicode_general_category_nil
-#define hb_unicode_decompose_compatibility_nil rive_hb_unicode_decompose_compatibility_nil
-// _hb_*
-#define hb_compiler_memory_r_barrier rive_hb_compiler_memory_r_barrier
-#define hb_head_t rive_hb_head_t
-#define hb_roundf rive_hb_roundf
-#define hb_debug_msg rive_hb_debug_msg
-#define hb_cmp_method rive_hb_cmp_method
-#define hb_glyph_info_is_zwj rive_hb_glyph_info_is_zwj
-#define hb_glyph_info_is_zwnj rive_hb_glyph_info_is_zwnj
-#define hb_grapheme_group_func rive_hb_grapheme_group_func
-#define hb_glyph_info_substituted rive_hb_glyph_info_substituted
-#define hb_atomic_ptr_impl_cmplexch rive_hb_atomic_ptr_impl_cmplexch
-#define hb_glyph_info_get_glyph_props rive_hb_glyph_info_get_glyph_props
-#define hb_glyph_info_is_continuation rive_hb_glyph_info_is_continuation
-#define hb_glyph_info_set_glyph_props rive_hb_glyph_info_set_glyph_props
-#define hb_glyph_info_is_unicode_format rive_hb_glyph_info_is_unicode_format
-#define hb_glyph_info_get_general_category rive_hb_glyph_info_get_general_category
-#define hb_glyph_info_is_default_ignorable_and_not_hidden rive_hb_glyph_info_is_default_ignorable_and_not_hidden
+#define _hb_ot_shape rive__hb_ot_shape
+#define _hb_ot_shaper_arabic rive__hb_ot_shaper_arabic
+#define _hb_ot_shaper_default rive__hb_ot_shaper_default
+#define _hb_ot_shaper_dumber rive__hb_ot_shaper_dumber
+#define _hb_ot_shaper_face_data_create rive__hb_ot_shaper_face_data_create
+#define _hb_ot_shaper_face_data_destroy rive__hb_ot_shaper_face_data_destroy
+#define _hb_ot_shaper_font_data_create rive__hb_ot_shaper_font_data_create
+#define _hb_ot_shaper_font_data_destroy rive__hb_ot_shaper_font_data_destroy
+#define _hb_ot_shaper_hangul rive__hb_ot_shaper_hangul
+#define _hb_ot_shaper_hebrew rive__hb_ot_shaper_hebrew
+#define _hb_ot_shaper_indic rive__hb_ot_shaper_indic
+#define _hb_ot_shaper_khmer rive__hb_ot_shaper_khmer
+#define _hb_ot_shaper_myanmar rive__hb_ot_shaper_myanmar
+#define _hb_ot_shaper_myanmar_zawgyi rive__hb_ot_shaper_myanmar_zawgyi
+#define _hb_ot_shaper_thai rive__hb_ot_shaper_thai
+#define _hb_ot_shaper_use rive__hb_ot_shaper_use
+#define _hb_shapers_get rive__hb_shapers_get
+#define _hb_subset_accelerator_user_data_key rive__hb_subset_accelerator_user_data_key
+#define _hb_unicode_is_emoji_Extended_Pictographic rive__hb_unicode_is_emoji_Extended_Pictographic
+#define accelerator_t rive_accelerator_t
+#define data_destroy_arabic rive_data_destroy_arabic
+#define endchar_str rive_endchar_str
+#define get_seac_components rive_get_seac_components
+#define glyf_accelerator_t rive_glyf_accelerator_t
+#define hb_aat_apply_context_t rive_hb_aat_apply_context_t
+#define hb_aat_feature_mapping_t rive_hb_aat_feature_mapping_t
+#define hb_aat_layout_compile_map rive_hb_aat_layout_compile_map
+#define hb_aat_layout_feature_selector_info_t rive_hb_aat_layout_feature_selector_info_t
 #define hb_aat_layout_feature_type_get_name_id rive_hb_aat_layout_feature_type_get_name_id
 #define hb_aat_layout_feature_type_get_selector_infos rive_hb_aat_layout_feature_type_get_selector_infos
+#define hb_aat_layout_feature_type_t rive_hb_aat_layout_feature_type_t
+#define hb_aat_layout_find_feature_mapping rive_hb_aat_layout_find_feature_mapping
 #define hb_aat_layout_get_feature_types rive_hb_aat_layout_get_feature_types
 #define hb_aat_layout_has_positioning rive_hb_aat_layout_has_positioning
 #define hb_aat_layout_has_substitution rive_hb_aat_layout_has_substitution
 #define hb_aat_layout_has_tracking rive_hb_aat_layout_has_tracking
-#define hb_blob_destroy rive_hb_blob_destroy
-#define hb_blob_get_data_writable rive_hb_blob_get_data_writable
-#define hb_blob_get_empty rive_hb_blob_get_empty
-#define hb_blob_make_immutable rive_hb_blob_make_immutable
-#define hb_blob_reference rive_hb_blob_reference
-#define hb_face_get_glyph_count rive_hb_face_get_glyph_count
-#define hb_face_reference_table rive_hb_face_reference_table
-#define hb_language_from_string rive_hb_language_from_string
-#define hb_language_matches rive_hb_language_matches
+#define hb_aat_layout_position rive_hb_aat_layout_position
+#define hb_aat_layout_remove_deleted_glyphs rive_hb_aat_layout_remove_deleted_glyphs
+#define hb_aat_layout_substitute rive_hb_aat_layout_substitute
+#define hb_aat_layout_track rive_hb_aat_layout_track
+#define hb_aat_map_builder_t rive_hb_aat_map_builder_t
+#define hb_aat_map_t rive_hb_aat_map_t
+#define hb_add rive_hb_add
+#define hb_all rive_hb_all
+#define hb_all_shapers rive_hb_all_shapers
+#define hb_alloc_pool_t rive_hb_alloc_pool_t
+#define hb_allocate_lig_id rive_hb_allocate_lig_id
+#define hb_angle_to_ratio rive_hb_angle_to_ratio
+#define hb_any rive_hb_any
+#define hb_apply rive_hb_apply
+#define hb_apply_morx rive_hb_apply_morx
+#define hb_apply_t rive_hb_apply_t
+#define hb_arabic_joining_b4 rive_hb_arabic_joining_b4
+#define hb_arabic_joining_joining_type rive_hb_arabic_joining_joining_type
+#define hb_arabic_joining_u8 rive_hb_arabic_joining_u8
+#define hb_arabic_pua_b4 rive_hb_arabic_pua_b4
+#define hb_arabic_pua_simp_map rive_hb_arabic_pua_simp_map
+#define hb_arabic_pua_trad_map rive_hb_arabic_pua_trad_map
+#define hb_arabic_pua_u16 rive_hb_arabic_pua_u16
+#define hb_arabic_pua_u8 rive_hb_arabic_pua_u8
+#define hb_array rive_hb_array
+#define hb_array_t rive_hb_array_t
+#define hb_ascii_t rive_hb_ascii_t
+#define hb_atomic_ptr_impl_cmplexch rive_hb_atomic_ptr_impl_cmplexch
+#define hb_atomic_t rive_hb_atomic_t
+#define hb_barrier rive_hb_barrier
+#define hb_bit_page_t rive_hb_bit_page_t
+#define hb_bit_set_invertible_t rive_hb_bit_set_invertible_t
+#define hb_bit_set_t rive_hb_bit_set_t
+#define hb_bit_storage rive_hb_bit_storage
+#define hb_bitwise_and rive_hb_bitwise_and
+#define hb_bitwise_gt rive_hb_bitwise_gt
+#define hb_bitwise_lt rive_hb_bitwise_lt
+#define hb_bitwise_neg rive_hb_bitwise_neg
+#define hb_bitwise_or rive_hb_bitwise_or
+#define hb_bitwise_xor rive_hb_bitwise_xor
 #define hb_blob_copy_writable_or_fail rive_hb_blob_copy_writable_or_fail
 #define hb_blob_create rive_hb_blob_create
 #define hb_blob_create_from_file rive_hb_blob_create_from_file
 #define hb_blob_create_from_file_or_fail rive_hb_blob_create_from_file_or_fail
 #define hb_blob_create_or_fail rive_hb_blob_create_or_fail
 #define hb_blob_create_sub_blob rive_hb_blob_create_sub_blob
+#define hb_blob_destroy rive_hb_blob_destroy
 #define hb_blob_get_data rive_hb_blob_get_data
+#define hb_blob_get_data_writable rive_hb_blob_get_data_writable
+#define hb_blob_get_empty rive_hb_blob_get_empty
 #define hb_blob_get_length rive_hb_blob_get_length
 #define hb_blob_get_user_data rive_hb_blob_get_user_data
 #define hb_blob_is_immutable rive_hb_blob_is_immutable
+#define hb_blob_make_immutable rive_hb_blob_make_immutable
+#define hb_blob_ptr_t rive_hb_blob_ptr_t
+#define hb_blob_reference rive_hb_blob_reference
 #define hb_blob_set_user_data rive_hb_blob_set_user_data
-#define hb_buffer_deserialize_json rive_hb_buffer_deserialize_json
-#define hb_buffer_serialize_formats rive_hb_buffer_serialize_formats
-#define hb_buffer_serialize_invalid rive_hb_buffer_serialize_invalid
-#define hb_buffer_serialize_glyphs_json rive_hb_buffer_serialize_glyphs_json
-#define hb_buffer_serialize_glyphs_text rive_hb_buffer_serialize_glyphs_text
-#define hb_buffer_serialize_unicode_json rive_hb_buffer_serialize_unicode_json
-#define hb_buffer_serialize_unicode_text rive_hb_buffer_serialize_unicode_text
-#define hb_buffer_deserialize_text_glyphs rive_hb_buffer_deserialize_text_glyphs
-#define hb_buffer_deserialize_text_unicode rive_hb_buffer_deserialize_text_unicode
-#define hb_buffer_deserialize_glyphs rive_hb_buffer_deserialize_glyphs
-#define hb_buffer_deserialize_unicode rive_hb_buffer_deserialize_unicode
-#define hb_buffer_get_glyph_infos rive_hb_buffer_get_glyph_infos
-#define hb_buffer_get_glyph_positions rive_hb_buffer_get_glyph_positions
-#define hb_buffer_serialize rive_hb_buffer_serialize
-#define hb_buffer_serialize_format_from_string rive_hb_buffer_serialize_format_from_string
-#define hb_buffer_serialize_format_to_string rive_hb_buffer_serialize_format_to_string
-#define hb_buffer_serialize_glyphs rive_hb_buffer_serialize_glyphs
-#define hb_buffer_serialize_list_formats rive_hb_buffer_serialize_list_formats
-#define hb_buffer_serialize_unicode rive_hb_buffer_serialize_unicode
-#define hb_buffer_set_content_type rive_hb_buffer_set_content_type
-#define hb_font_get_empty rive_hb_font_get_empty
-#define hb_font_get_glyph_extents rive_hb_font_get_glyph_extents
-#define hb_font_glyph_from_string rive_hb_font_glyph_from_string
-#define hb_font_glyph_to_string rive_hb_font_glyph_to_string
-#define hb_tag_from_string rive_hb_tag_from_string
-#define hb_buffer_append rive_hb_buffer_append
-#define hb_buffer_clear_contents rive_hb_buffer_clear_contents
-#define hb_buffer_create_similar rive_hb_buffer_create_similar
-#define hb_buffer_destroy rive_hb_buffer_destroy
-#define hb_buffer_diff rive_hb_buffer_diff
-#define hb_buffer_get_direction rive_hb_buffer_get_direction
-#define hb_buffer_get_flags rive_hb_buffer_get_flags
-#define hb_buffer_get_segment_properties rive_hb_buffer_get_segment_properties
-#define hb_buffer_reverse rive_hb_buffer_reverse
-#define hb_buffer_set_flags rive_hb_buffer_set_flags
-#define hb_buffer_set_length rive_hb_buffer_set_length
-#define hb_buffer_set_segment_properties rive_hb_buffer_set_segment_properties
-#define hb_shape_full rive_hb_shape_full
+#define hb_blob_t rive_hb_blob_t
+#define hb_bool rive_hb_bool
+#define hb_bounds_t rive_hb_bounds_t
+#define hb_bsearch rive_hb_bsearch
+#define hb_bsearch_impl rive_hb_bsearch_impl
 #define hb_buffer_add rive_hb_buffer_add
 #define hb_buffer_add_codepoints rive_hb_buffer_add_codepoints
 #define hb_buffer_add_latin1 rive_hb_buffer_add_latin1
+#define hb_buffer_add_utf rive_hb_buffer_add_utf
 #define hb_buffer_add_utf16 rive_hb_buffer_add_utf16
 #define hb_buffer_add_utf32 rive_hb_buffer_add_utf32
 #define hb_buffer_add_utf8 rive_hb_buffer_add_utf8
+#define hb_buffer_allocate_gsubgpos_vars rive_hb_buffer_allocate_gsubgpos_vars
+#define hb_buffer_allocate_unicode_vars rive_hb_buffer_allocate_unicode_vars
 #define hb_buffer_allocation_successful rive_hb_buffer_allocation_successful
+#define hb_buffer_append rive_hb_buffer_append
+#define hb_buffer_assert_gsubgpos_vars rive_hb_buffer_assert_gsubgpos_vars
+#define hb_buffer_assert_unicode_vars rive_hb_buffer_assert_unicode_vars
+#define hb_buffer_clear_contents rive_hb_buffer_clear_contents
 #define hb_buffer_create rive_hb_buffer_create
+#define hb_buffer_create_similar rive_hb_buffer_create_similar
+#define hb_buffer_deallocate_gsubgpos_vars rive_hb_buffer_deallocate_gsubgpos_vars
+#define hb_buffer_deallocate_unicode_vars rive_hb_buffer_deallocate_unicode_vars
+#define hb_buffer_deserialize_glyphs rive_hb_buffer_deserialize_glyphs
+#define hb_buffer_deserialize_unicode rive_hb_buffer_deserialize_unicode
+#define hb_buffer_destroy rive_hb_buffer_destroy
+#define hb_buffer_diff rive_hb_buffer_diff
+#define hb_buffer_diff_flags_t rive_hb_buffer_diff_flags_t
+#define hb_buffer_flags_t rive_hb_buffer_flags_t
 #define hb_buffer_get_cluster_level rive_hb_buffer_get_cluster_level
 #define hb_buffer_get_content_type rive_hb_buffer_get_content_type
+#define hb_buffer_get_direction rive_hb_buffer_get_direction
 #define hb_buffer_get_empty rive_hb_buffer_get_empty
+#define hb_buffer_get_flags rive_hb_buffer_get_flags
+#define hb_buffer_get_glyph_infos rive_hb_buffer_get_glyph_infos
+#define hb_buffer_get_glyph_positions rive_hb_buffer_get_glyph_positions
 #define hb_buffer_get_invisible_glyph rive_hb_buffer_get_invisible_glyph
 #define hb_buffer_get_language rive_hb_buffer_get_language
 #define hb_buffer_get_length rive_hb_buffer_get_length
 #define hb_buffer_get_not_found_glyph rive_hb_buffer_get_not_found_glyph
+#define hb_buffer_get_not_found_variation_selector_glyph rive_hb_buffer_get_not_found_variation_selector_glyph
+#define hb_buffer_get_random_state rive_hb_buffer_get_random_state
 #define hb_buffer_get_replacement_codepoint rive_hb_buffer_get_replacement_codepoint
 #define hb_buffer_get_script rive_hb_buffer_get_script
+#define hb_buffer_get_segment_properties rive_hb_buffer_get_segment_properties
 #define hb_buffer_get_unicode_funcs rive_hb_buffer_get_unicode_funcs
 #define hb_buffer_get_user_data rive_hb_buffer_get_user_data
 #define hb_buffer_guess_segment_properties rive_hb_buffer_guess_segment_properties
@@ -531,111 +172,207 @@
 #define hb_buffer_pre_allocate rive_hb_buffer_pre_allocate
 #define hb_buffer_reference rive_hb_buffer_reference
 #define hb_buffer_reset rive_hb_buffer_reset
+#define hb_buffer_reverse rive_hb_buffer_reverse
 #define hb_buffer_reverse_clusters rive_hb_buffer_reverse_clusters
 #define hb_buffer_reverse_range rive_hb_buffer_reverse_range
+#define hb_buffer_scratch_flags_t rive_hb_buffer_scratch_flags_t
+#define hb_buffer_serialize rive_hb_buffer_serialize
+#define hb_buffer_serialize_flags_t rive_hb_buffer_serialize_flags_t
+#define hb_buffer_serialize_format_from_string rive_hb_buffer_serialize_format_from_string
+#define hb_buffer_serialize_format_t rive_hb_buffer_serialize_format_t
+#define hb_buffer_serialize_format_to_string rive_hb_buffer_serialize_format_to_string
+#define hb_buffer_serialize_glyphs rive_hb_buffer_serialize_glyphs
+#define hb_buffer_serialize_list_formats rive_hb_buffer_serialize_list_formats
+#define hb_buffer_serialize_unicode rive_hb_buffer_serialize_unicode
 #define hb_buffer_set_cluster_level rive_hb_buffer_set_cluster_level
+#define hb_buffer_set_content_type rive_hb_buffer_set_content_type
 #define hb_buffer_set_direction rive_hb_buffer_set_direction
+#define hb_buffer_set_flags rive_hb_buffer_set_flags
 #define hb_buffer_set_invisible_glyph rive_hb_buffer_set_invisible_glyph
 #define hb_buffer_set_language rive_hb_buffer_set_language
+#define hb_buffer_set_length rive_hb_buffer_set_length
 #define hb_buffer_set_message_func rive_hb_buffer_set_message_func
 #define hb_buffer_set_not_found_glyph rive_hb_buffer_set_not_found_glyph
+#define hb_buffer_set_not_found_variation_selector_glyph rive_hb_buffer_set_not_found_variation_selector_glyph
+#define hb_buffer_set_random_state rive_hb_buffer_set_random_state
 #define hb_buffer_set_replacement_codepoint rive_hb_buffer_set_replacement_codepoint
 #define hb_buffer_set_script rive_hb_buffer_set_script
+#define hb_buffer_set_segment_properties rive_hb_buffer_set_segment_properties
 #define hb_buffer_set_unicode_funcs rive_hb_buffer_set_unicode_funcs
 #define hb_buffer_set_user_data rive_hb_buffer_set_user_data
-#define hb_script_get_horizontal_direction rive_hb_script_get_horizontal_direction
-#define hb_segment_properties_equal rive_hb_segment_properties_equal
-#define hb_segment_properties_hash rive_hb_segment_properties_hash
-#define hb_segment_properties_overlay rive_hb_segment_properties_overlay
-#define hb_unicode_funcs_destroy rive_hb_unicode_funcs_destroy
-#define hb_unicode_funcs_get_default rive_hb_unicode_funcs_get_default
-#define hb_unicode_funcs_reference rive_hb_unicode_funcs_reference
-#define hb_options_init rive_hb_options_init
+#define hb_buffer_t rive_hb_buffer_t
+#define hb_cache_t rive_hb_cache_t
+#define hb_calloc rive_hb_calloc
+#define hb_ceil_to_4 rive_hb_ceil_to_4
+#define hb_clamp rive_hb_clamp
+#define hb_clear_substitution_flags rive_hb_clear_substitution_flags
+#define hb_cmp_method rive_hb_cmp_method
+#define hb_cmp_operator rive_hb_cmp_operator
+#define hb_codepoint_is_regional_indicator rive_hb_codepoint_is_regional_indicator
+#define hb_codepoint_parse rive_hb_codepoint_parse
+#define hb_collect_features_context_t rive_hb_collect_features_context_t
+#define hb_color_line_get_color_stops rive_hb_color_line_get_color_stops
+#define hb_color_line_get_extend rive_hb_color_line_get_extend
+#define hb_color_line_t rive_hb_color_line_t
+#define hb_color_stop_t rive_hb_color_stop_t
+#define hb_colr_scratch_t rive_hb_colr_scratch_t
+#define hb_compiler_memory_r_barrier rive_hb_compiler_memory_r_barrier
+#define hb_concat rive_hb_concat
+#define hb_concat_iter_t rive_hb_concat_iter_t
+#define hb_copy rive_hb_copy
+#define hb_coretext_draw_glyph_or_fail rive_hb_coretext_draw_glyph_or_fail
+#define hb_coretext_face_create_from_blob_or_fail rive_hb_coretext_face_create_from_blob_or_fail
+#define hb_coretext_face_create_from_file_or_fail rive_hb_coretext_face_create_from_file_or_fail
+#define hb_coretext_face_data_t rive_hb_coretext_face_data_t
+#define hb_coretext_font_data_t rive_hb_coretext_font_data_t
+#define hb_coretext_font_funcs_lazy_loader_t rive_hb_coretext_font_funcs_lazy_loader_t
+#define hb_coretext_font_get_ct_font rive_hb_coretext_font_get_ct_font
+#define hb_coretext_font_set_funcs rive_hb_coretext_font_set_funcs
+#define hb_coretext_get_font_funcs rive_hb_coretext_get_font_funcs
+#define hb_coretext_get_font_h_extents rive_hb_coretext_get_font_h_extents
+#define hb_coretext_get_glyph_extents rive_hb_coretext_get_glyph_extents
+#define hb_coretext_get_glyph_h_advances rive_hb_coretext_get_glyph_h_advances
+#define hb_coretext_get_nominal_glyph rive_hb_coretext_get_nominal_glyph
+#define hb_coretext_get_nominal_glyphs rive_hb_coretext_get_nominal_glyphs
+#define hb_coretext_get_variation_glyph rive_hb_coretext_get_variation_glyph
+#define hb_ctz rive_hb_ctz
+#define hb_data_wrapper_t rive_hb_data_wrapper_t
+#define hb_debug rive_hb_debug
+#define hb_debug_msg rive_hb_debug_msg
+#define hb_decycler_node_t rive_hb_decycler_node_t
+#define hb_decycler_t rive_hb_decycler_t
+#define hb_deref rive_hb_deref
 #define hb_direction_from_string rive_hb_direction_from_string
+#define hb_direction_t rive_hb_direction_t
 #define hb_direction_to_string rive_hb_direction_to_string
-#define hb_feature_from_string rive_hb_feature_from_string
-#define hb_feature_to_string rive_hb_feature_to_string
-#define hb_language_to_string rive_hb_language_to_string
-#define hb_script_from_iso15924_tag rive_hb_script_from_iso15924_tag
-#define hb_script_from_string rive_hb_script_from_string
-#define hb_script_to_iso15924_tag rive_hb_script_to_iso15924_tag
-#define hb_tag_to_string rive_hb_tag_to_string
-#define hb_variation_from_string rive_hb_variation_from_string
-#define hb_variation_to_string rive_hb_variation_to_string
-#define hb_version rive_hb_version
-#define hb_version_atleast rive_hb_version_atleast
-#define hb_version_string rive_hb_version_string
-#define hb_draw_funcs_set_middle rive_hb_draw_funcs_set_middle
-#define hb_draw_funcs_set_preamble rive_hb_draw_funcs_set_preamble
+#define hb_dispatch_context_t rive_hb_dispatch_context_t
+#define hb_do_destroy rive_hb_do_destroy
+#define hb_drain rive_hb_drain
 #define hb_draw_close_path rive_hb_draw_close_path
+#define hb_draw_close_path_default rive_hb_draw_close_path_default
+#define hb_draw_close_path_nil rive_hb_draw_close_path_nil
 #define hb_draw_cubic_to rive_hb_draw_cubic_to
+#define hb_draw_cubic_to_default rive_hb_draw_cubic_to_default
+#define hb_draw_cubic_to_nil rive_hb_draw_cubic_to_nil
+#define hb_draw_extents_cubic_to rive_hb_draw_extents_cubic_to
+#define hb_draw_extents_funcs_lazy_loader_t rive_hb_draw_extents_funcs_lazy_loader_t
+#define hb_draw_extents_get_funcs rive_hb_draw_extents_get_funcs
+#define hb_draw_extents_line_to rive_hb_draw_extents_line_to
+#define hb_draw_extents_move_to rive_hb_draw_extents_move_to
+#define hb_draw_extents_quadratic_to rive_hb_draw_extents_quadratic_to
 #define hb_draw_funcs_create rive_hb_draw_funcs_create
+#define hb_draw_funcs_default rive_hb_draw_funcs_default
 #define hb_draw_funcs_destroy rive_hb_draw_funcs_destroy
 #define hb_draw_funcs_get_empty rive_hb_draw_funcs_get_empty
 #define hb_draw_funcs_get_user_data rive_hb_draw_funcs_get_user_data
 #define hb_draw_funcs_is_immutable rive_hb_draw_funcs_is_immutable
+#define hb_draw_funcs_lazy_loader_t rive_hb_draw_funcs_lazy_loader_t
 #define hb_draw_funcs_make_immutable rive_hb_draw_funcs_make_immutable
 #define hb_draw_funcs_reference rive_hb_draw_funcs_reference
 #define hb_draw_funcs_set_close_path_func rive_hb_draw_funcs_set_close_path_func
 #define hb_draw_funcs_set_cubic_to_func rive_hb_draw_funcs_set_cubic_to_func
 #define hb_draw_funcs_set_line_to_func rive_hb_draw_funcs_set_line_to_func
+#define hb_draw_funcs_set_middle rive_hb_draw_funcs_set_middle
 #define hb_draw_funcs_set_move_to_func rive_hb_draw_funcs_set_move_to_func
+#define hb_draw_funcs_set_preamble rive_hb_draw_funcs_set_preamble
 #define hb_draw_funcs_set_quadratic_to_func rive_hb_draw_funcs_set_quadratic_to_func
 #define hb_draw_funcs_set_user_data rive_hb_draw_funcs_set_user_data
+#define hb_draw_funcs_t rive_hb_draw_funcs_t
 #define hb_draw_line_to rive_hb_draw_line_to
+#define hb_draw_line_to_default rive_hb_draw_line_to_default
+#define hb_draw_line_to_nil rive_hb_draw_line_to_nil
 #define hb_draw_move_to rive_hb_draw_move_to
+#define hb_draw_move_to_default rive_hb_draw_move_to_default
+#define hb_draw_move_to_nil rive_hb_draw_move_to_nil
 #define hb_draw_quadratic_to rive_hb_draw_quadratic_to
-#define hb_arabic_b2 rive_hb_arabic_b2
-#define hb_arabic_b4 rive_hb_arabic_b4
-#define hb_arabic_u8 rive_hb_arabic_u8
-#define hb_arabic_u16 rive_hb_arabic_u16
-#define hb_arabic_pua_simp_map rive_hb_arabic_pua_simp_map
-#define hb_arabic_pua_trad_map rive_hb_arabic_pua_trad_map
-#define hb_face_for_data_closure_create rive_hb_face_for_data_closure_create
-#define hb_face_for_data_closure_destroy rive_hb_face_for_data_closure_destroy
-#define hb_face_for_data_reference_table rive_hb_face_for_data_reference_table
+#define hb_draw_quadratic_to_default rive_hb_draw_quadratic_to_default
+#define hb_draw_quadratic_to_nil rive_hb_draw_quadratic_to_nil
+#define hb_draw_session_t rive_hb_draw_session_t
+#define hb_draw_state_t rive_hb_draw_state_t
+#define hb_emoji_b1 rive_hb_emoji_b1
+#define hb_emoji_b4 rive_hb_emoji_b4
+#define hb_emoji_is_Extended_Pictographic rive_hb_emoji_is_Extended_Pictographic
+#define hb_emoji_u8 rive_hb_emoji_u8
+#define hb_empty_t rive_hb_empty_t
+#define hb_ensure_native_direction rive_hb_ensure_native_direction
+#define hb_enumerate rive_hb_enumerate
+#define hb_equal rive_hb_equal
+#define hb_extents_t rive_hb_extents_t
+#define hb_face_builder_add_table rive_hb_face_builder_add_table
+#define hb_face_builder_create rive_hb_face_builder_create
+#define hb_face_builder_data_create rive_hb_face_builder_data_create
+#define hb_face_builder_data_destroy rive_hb_face_builder_data_destroy
+#define hb_face_builder_data_reference_blob rive_hb_face_builder_data_reference_blob
+#define hb_face_builder_get_table_tags rive_hb_face_builder_get_table_tags
+#define hb_face_builder_reference_table rive_hb_face_builder_reference_table
+#define hb_face_builder_sort_tables rive_hb_face_builder_sort_tables
 #define hb_face_collect_nominal_glyph_mapping rive_hb_face_collect_nominal_glyph_mapping
 #define hb_face_collect_unicodes rive_hb_face_collect_unicodes
 #define hb_face_collect_variation_selectors rive_hb_face_collect_variation_selectors
 #define hb_face_collect_variation_unicodes rive_hb_face_collect_variation_unicodes
 #define hb_face_count rive_hb_face_count
 #define hb_face_create rive_hb_face_create
-#define hb_face_create_or_fail rive_hb_face_create_or_fail
 #define hb_face_create_for_tables rive_hb_face_create_for_tables
+#define hb_face_create_from_file_or_fail rive_hb_face_create_from_file_or_fail
+#define hb_face_create_from_file_or_fail_using rive_hb_face_create_from_file_or_fail_using
+#define hb_face_create_or_fail rive_hb_face_create_or_fail
+#define hb_face_create_or_fail_using rive_hb_face_create_or_fail_using
 #define hb_face_destroy rive_hb_face_destroy
+#define hb_face_for_data_closure_create rive_hb_face_for_data_closure_create
+#define hb_face_for_data_closure_destroy rive_hb_face_for_data_closure_destroy
+#define hb_face_for_data_get_table_tags rive_hb_face_for_data_get_table_tags
+#define hb_face_for_data_reference_table rive_hb_face_for_data_reference_table
 #define hb_face_get_empty rive_hb_face_get_empty
+#define hb_face_get_glyph_count rive_hb_face_get_glyph_count
 #define hb_face_get_index rive_hb_face_get_index
 #define hb_face_get_table_tags rive_hb_face_get_table_tags
 #define hb_face_get_upem rive_hb_face_get_upem
 #define hb_face_get_user_data rive_hb_face_get_user_data
 #define hb_face_is_immutable rive_hb_face_is_immutable
+#define hb_face_lazy_loader_t rive_hb_face_lazy_loader_t
+#define hb_face_list_loaders rive_hb_face_list_loaders
+#define hb_face_loader_list_lazy_loader_t rive_hb_face_loader_list_lazy_loader_t
 #define hb_face_make_immutable rive_hb_face_make_immutable
 #define hb_face_reference rive_hb_face_reference
 #define hb_face_reference_blob rive_hb_face_reference_blob
+#define hb_face_reference_table rive_hb_face_reference_table
+#define hb_face_set_get_table_tags_func rive_hb_face_set_get_table_tags_func
 #define hb_face_set_glyph_count rive_hb_face_set_glyph_count
 #define hb_face_set_index rive_hb_face_set_index
 #define hb_face_set_upem rive_hb_face_set_upem
 #define hb_face_set_user_data rive_hb_face_set_user_data
-#define hb_shape_plan_destroy rive_hb_shape_plan_destroy
-#define hb_font_create rive_hb_font_create
-#define hb_draw_funcs_default rive_hb_draw_funcs_default
-#define hb_font_funcs_default rive_hb_font_funcs_default
-#define hb_font_adopt_var_coords rive_hb_font_adopt_var_coords
-#define hb_font_funcs_set_middle rive_hb_font_funcs_set_middle
-#define hb_font_funcs_set_preamble rive_hb_font_funcs_set_preamble
+#define hb_face_t rive_hb_face_t
+#define hb_feature_from_string rive_hb_feature_from_string
+#define hb_feature_t rive_hb_feature_t
+#define hb_feature_to_string rive_hb_feature_to_string
+#define hb_fill rive_hb_fill
+#define hb_filter rive_hb_filter
+#define hb_filter_iter_factory_t rive_hb_filter_iter_factory_t
+#define hb_filter_iter_t rive_hb_filter_iter_t
+#define hb_first rive_hb_first
 #define hb_font_add_glyph_origin_for_direction rive_hb_font_add_glyph_origin_for_direction
+#define hb_font_adopt_var_coords rive_hb_font_adopt_var_coords
 #define hb_font_changed rive_hb_font_changed
+#define hb_font_create rive_hb_font_create
 #define hb_font_create_sub_font rive_hb_font_create_sub_font
 #define hb_font_destroy rive_hb_font_destroy
 #define hb_font_draw_glyph rive_hb_font_draw_glyph
+#define hb_font_draw_glyph_or_fail rive_hb_font_draw_glyph_or_fail
+#define hb_font_draw_glyph_or_fail_default rive_hb_font_draw_glyph_or_fail_default
+#define hb_font_draw_glyph_or_fail_nil rive_hb_font_draw_glyph_or_fail_nil
+#define hb_font_extents_t rive_hb_font_extents_t
 #define hb_font_funcs_create rive_hb_font_funcs_create
+#define hb_font_funcs_default rive_hb_font_funcs_default
 #define hb_font_funcs_destroy rive_hb_font_funcs_destroy
 #define hb_font_funcs_get_empty rive_hb_font_funcs_get_empty
 #define hb_font_funcs_get_user_data rive_hb_font_funcs_get_user_data
 #define hb_font_funcs_is_immutable rive_hb_font_funcs_is_immutable
+#define hb_font_funcs_lazy_loader_t rive_hb_font_funcs_lazy_loader_t
+#define hb_font_funcs_list_lazy_loader_t rive_hb_font_funcs_list_lazy_loader_t
 #define hb_font_funcs_make_immutable rive_hb_font_funcs_make_immutable
 #define hb_font_funcs_reference rive_hb_font_funcs_reference
 #define hb_font_funcs_set_draw_glyph_func rive_hb_font_funcs_set_draw_glyph_func
+#define hb_font_funcs_set_draw_glyph_or_fail_func rive_hb_font_funcs_set_draw_glyph_or_fail_func
 #define hb_font_funcs_set_font_h_extents_func rive_hb_font_funcs_set_font_h_extents_func
 #define hb_font_funcs_set_font_v_extents_func rive_hb_font_funcs_set_font_v_extents_func
 #define hb_font_funcs_set_glyph_contour_point_func rive_hb_font_funcs_set_glyph_contour_point_func
@@ -646,41 +383,83 @@
 #define hb_font_funcs_set_glyph_h_advances_func rive_hb_font_funcs_set_glyph_h_advances_func
 #define hb_font_funcs_set_glyph_h_kerning_func rive_hb_font_funcs_set_glyph_h_kerning_func
 #define hb_font_funcs_set_glyph_h_origin_func rive_hb_font_funcs_set_glyph_h_origin_func
+#define hb_font_funcs_set_glyph_h_origins_func rive_hb_font_funcs_set_glyph_h_origins_func
 #define hb_font_funcs_set_glyph_name_func rive_hb_font_funcs_set_glyph_name_func
 #define hb_font_funcs_set_glyph_shape_func rive_hb_font_funcs_set_glyph_shape_func
 #define hb_font_funcs_set_glyph_v_advance_func rive_hb_font_funcs_set_glyph_v_advance_func
 #define hb_font_funcs_set_glyph_v_advances_func rive_hb_font_funcs_set_glyph_v_advances_func
 #define hb_font_funcs_set_glyph_v_kerning_func rive_hb_font_funcs_set_glyph_v_kerning_func
 #define hb_font_funcs_set_glyph_v_origin_func rive_hb_font_funcs_set_glyph_v_origin_func
+#define hb_font_funcs_set_glyph_v_origins_func rive_hb_font_funcs_set_glyph_v_origins_func
+#define hb_font_funcs_set_middle rive_hb_font_funcs_set_middle
 #define hb_font_funcs_set_nominal_glyph_func rive_hb_font_funcs_set_nominal_glyph_func
 #define hb_font_funcs_set_nominal_glyphs_func rive_hb_font_funcs_set_nominal_glyphs_func
 #define hb_font_funcs_set_paint_glyph_func rive_hb_font_funcs_set_paint_glyph_func
+#define hb_font_funcs_set_paint_glyph_or_fail_func rive_hb_font_funcs_set_paint_glyph_or_fail_func
+#define hb_font_funcs_set_preamble rive_hb_font_funcs_set_preamble
 #define hb_font_funcs_set_user_data rive_hb_font_funcs_set_user_data
 #define hb_font_funcs_set_variation_glyph_func rive_hb_font_funcs_set_variation_glyph_func
+#define hb_font_funcs_t rive_hb_font_funcs_t
+#define hb_font_get_empty rive_hb_font_get_empty
 #define hb_font_get_extents_for_direction rive_hb_font_get_extents_for_direction
 #define hb_font_get_face rive_hb_font_get_face
+#define hb_font_get_font_h_extents_default rive_hb_font_get_font_h_extents_default
+#define hb_font_get_font_h_extents_nil rive_hb_font_get_font_h_extents_nil
+#define hb_font_get_font_v_extents_default rive_hb_font_get_font_v_extents_default
+#define hb_font_get_font_v_extents_nil rive_hb_font_get_font_v_extents_nil
 #define hb_font_get_glyph rive_hb_font_get_glyph
 #define hb_font_get_glyph_advance_for_direction rive_hb_font_get_glyph_advance_for_direction
 #define hb_font_get_glyph_advances_for_direction rive_hb_font_get_glyph_advances_for_direction
 #define hb_font_get_glyph_contour_point rive_hb_font_get_glyph_contour_point
+#define hb_font_get_glyph_contour_point_default rive_hb_font_get_glyph_contour_point_default
 #define hb_font_get_glyph_contour_point_for_origin rive_hb_font_get_glyph_contour_point_for_origin
+#define hb_font_get_glyph_contour_point_nil rive_hb_font_get_glyph_contour_point_nil
+#define hb_font_get_glyph_extents rive_hb_font_get_glyph_extents
+#define hb_font_get_glyph_extents_default rive_hb_font_get_glyph_extents_default
 #define hb_font_get_glyph_extents_for_origin rive_hb_font_get_glyph_extents_for_origin
+#define hb_font_get_glyph_extents_nil rive_hb_font_get_glyph_extents_nil
 #define hb_font_get_glyph_from_name rive_hb_font_get_glyph_from_name
+#define hb_font_get_glyph_from_name_default rive_hb_font_get_glyph_from_name_default
+#define hb_font_get_glyph_from_name_nil rive_hb_font_get_glyph_from_name_nil
 #define hb_font_get_glyph_h_advance rive_hb_font_get_glyph_h_advance
+#define hb_font_get_glyph_h_advance_default rive_hb_font_get_glyph_h_advance_default
+#define hb_font_get_glyph_h_advance_nil rive_hb_font_get_glyph_h_advance_nil
 #define hb_font_get_glyph_h_advances rive_hb_font_get_glyph_h_advances
+#define hb_font_get_glyph_h_advances_default rive_hb_font_get_glyph_h_advances_default
 #define hb_font_get_glyph_h_kerning rive_hb_font_get_glyph_h_kerning
+#define hb_font_get_glyph_h_kerning_default rive_hb_font_get_glyph_h_kerning_default
+#define hb_font_get_glyph_h_kerning_nil rive_hb_font_get_glyph_h_kerning_nil
 #define hb_font_get_glyph_h_origin rive_hb_font_get_glyph_h_origin
+#define hb_font_get_glyph_h_origin_default rive_hb_font_get_glyph_h_origin_default
+#define hb_font_get_glyph_h_origin_nil rive_hb_font_get_glyph_h_origin_nil
+#define hb_font_get_glyph_h_origins rive_hb_font_get_glyph_h_origins
+#define hb_font_get_glyph_h_origins_default rive_hb_font_get_glyph_h_origins_default
 #define hb_font_get_glyph_kerning_for_direction rive_hb_font_get_glyph_kerning_for_direction
 #define hb_font_get_glyph_name rive_hb_font_get_glyph_name
+#define hb_font_get_glyph_name_default rive_hb_font_get_glyph_name_default
+#define hb_font_get_glyph_name_nil rive_hb_font_get_glyph_name_nil
 #define hb_font_get_glyph_origin_for_direction rive_hb_font_get_glyph_origin_for_direction
 #define hb_font_get_glyph_shape rive_hb_font_get_glyph_shape
 #define hb_font_get_glyph_v_advance rive_hb_font_get_glyph_v_advance
+#define hb_font_get_glyph_v_advance_default rive_hb_font_get_glyph_v_advance_default
+#define hb_font_get_glyph_v_advance_nil rive_hb_font_get_glyph_v_advance_nil
 #define hb_font_get_glyph_v_advances rive_hb_font_get_glyph_v_advances
+#define hb_font_get_glyph_v_advances_default rive_hb_font_get_glyph_v_advances_default
 #define hb_font_get_glyph_v_kerning rive_hb_font_get_glyph_v_kerning
+#define hb_font_get_glyph_v_kerning_default rive_hb_font_get_glyph_v_kerning_default
+#define hb_font_get_glyph_v_kerning_nil rive_hb_font_get_glyph_v_kerning_nil
 #define hb_font_get_glyph_v_origin rive_hb_font_get_glyph_v_origin
+#define hb_font_get_glyph_v_origin_default rive_hb_font_get_glyph_v_origin_default
+#define hb_font_get_glyph_v_origin_nil rive_hb_font_get_glyph_v_origin_nil
+#define hb_font_get_glyph_v_origins rive_hb_font_get_glyph_v_origins
+#define hb_font_get_glyph_v_origins_default rive_hb_font_get_glyph_v_origins_default
 #define hb_font_get_h_extents rive_hb_font_get_h_extents
 #define hb_font_get_nominal_glyph rive_hb_font_get_nominal_glyph
+#define hb_font_get_nominal_glyph_default rive_hb_font_get_nominal_glyph_default
+#define hb_font_get_nominal_glyph_nil rive_hb_font_get_nominal_glyph_nil
+#define hb_font_get_nominal_glyph_trampoline rive_hb_font_get_nominal_glyph_trampoline
 #define hb_font_get_nominal_glyphs rive_hb_font_get_nominal_glyphs
+#define hb_font_get_nominal_glyphs_default rive_hb_font_get_nominal_glyphs_default
 #define hb_font_get_parent rive_hb_font_get_parent
 #define hb_font_get_ppem rive_hb_font_get_ppem
 #define hb_font_get_ptem rive_hb_font_get_ptem
@@ -694,13 +473,24 @@
 #define hb_font_get_var_coords_normalized rive_hb_font_get_var_coords_normalized
 #define hb_font_get_var_named_instance rive_hb_font_get_var_named_instance
 #define hb_font_get_variation_glyph rive_hb_font_get_variation_glyph
+#define hb_font_get_variation_glyph_default rive_hb_font_get_variation_glyph_default
+#define hb_font_get_variation_glyph_nil rive_hb_font_get_variation_glyph_nil
+#define hb_font_get_variation_glyph_trampoline rive_hb_font_get_variation_glyph_trampoline
+#define hb_font_glyph_from_string rive_hb_font_glyph_from_string
+#define hb_font_glyph_to_string rive_hb_font_glyph_to_string
 #define hb_font_is_immutable rive_hb_font_is_immutable
+#define hb_font_is_synthetic rive_hb_font_is_synthetic
+#define hb_font_list_funcs rive_hb_font_list_funcs
 #define hb_font_make_immutable rive_hb_font_make_immutable
 #define hb_font_paint_glyph rive_hb_font_paint_glyph
+#define hb_font_paint_glyph_or_fail rive_hb_font_paint_glyph_or_fail
+#define hb_font_paint_glyph_or_fail_default rive_hb_font_paint_glyph_or_fail_default
+#define hb_font_paint_glyph_or_fail_nil rive_hb_font_paint_glyph_or_fail_nil
 #define hb_font_reference rive_hb_font_reference
 #define hb_font_set_face rive_hb_font_set_face
 #define hb_font_set_funcs rive_hb_font_set_funcs
 #define hb_font_set_funcs_data rive_hb_font_set_funcs_data
+#define hb_font_set_funcs_using rive_hb_font_set_funcs_using
 #define hb_font_set_parent rive_hb_font_set_parent
 #define hb_font_set_ppem rive_hb_font_set_ppem
 #define hb_font_set_ptem rive_hb_font_set_ptem
@@ -714,9 +504,95 @@
 #define hb_font_set_variation rive_hb_font_set_variation
 #define hb_font_set_variations rive_hb_font_set_variations
 #define hb_font_subtract_glyph_origin_for_direction rive_hb_font_subtract_glyph_origin_for_direction
-#define hb_ot_font_set_funcs rive_hb_ot_font_set_funcs
-#define hb_ot_var_named_instance_get_design_coords rive_hb_ot_var_named_instance_get_design_coords
-#define hb_ot_var_normalize_coords rive_hb_ot_var_normalize_coords
+#define hb_font_t rive_hb_font_t
+#define hb_form_clusters rive_hb_form_clusters
+#define hb_free rive_hb_free
+#define hb_free_pool_t rive_hb_free_pool_t
+#define hb_get rive_hb_get
+#define hb_get_glyph_alternates_dispatch_t rive_hb_get_glyph_alternates_dispatch_t
+#define hb_glyf_scratch_t rive_hb_glyf_scratch_t
+#define hb_glyph_extents_t rive_hb_glyph_extents_t
+#define hb_glyph_flags_t rive_hb_glyph_flags_t
+#define hb_glyph_info_clear_continuation rive_hb_glyph_info_clear_continuation
+#define hb_glyph_info_clear_default_ignorable rive_hb_glyph_info_clear_default_ignorable
+#define hb_glyph_info_clear_lig_props rive_hb_glyph_info_clear_lig_props
+#define hb_glyph_info_clear_ligated_and_multiplied rive_hb_glyph_info_clear_ligated_and_multiplied
+#define hb_glyph_info_clear_substituted rive_hb_glyph_info_clear_substituted
+#define hb_glyph_info_get_general_category rive_hb_glyph_info_get_general_category
+#define hb_glyph_info_get_glyph_props rive_hb_glyph_info_get_glyph_props
+#define hb_glyph_info_get_lig_comp rive_hb_glyph_info_get_lig_comp
+#define hb_glyph_info_get_lig_id rive_hb_glyph_info_get_lig_id
+#define hb_glyph_info_get_lig_num_comps rive_hb_glyph_info_get_lig_num_comps
+#define hb_glyph_info_get_modified_combining_class rive_hb_glyph_info_get_modified_combining_class
+#define hb_glyph_info_get_unicode_space_fallback_type rive_hb_glyph_info_get_unicode_space_fallback_type
+#define hb_glyph_info_is_aat_deleted rive_hb_glyph_info_is_aat_deleted
+#define hb_glyph_info_is_base_glyph rive_hb_glyph_info_is_base_glyph
+#define hb_glyph_info_is_continuation rive_hb_glyph_info_is_continuation
+#define hb_glyph_info_is_default_ignorable rive_hb_glyph_info_is_default_ignorable
+#define hb_glyph_info_is_hidden rive_hb_glyph_info_is_hidden
+#define hb_glyph_info_is_ligature rive_hb_glyph_info_is_ligature
+#define hb_glyph_info_is_mark rive_hb_glyph_info_is_mark
+#define hb_glyph_info_is_unicode_format rive_hb_glyph_info_is_unicode_format
+#define hb_glyph_info_is_unicode_mark rive_hb_glyph_info_is_unicode_mark
+#define hb_glyph_info_is_unicode_space rive_hb_glyph_info_is_unicode_space
+#define hb_glyph_info_is_variation_selector rive_hb_glyph_info_is_variation_selector
+#define hb_glyph_info_is_zwj rive_hb_glyph_info_is_zwj
+#define hb_glyph_info_is_zwnj rive_hb_glyph_info_is_zwnj
+#define hb_glyph_info_ligated rive_hb_glyph_info_ligated
+#define hb_glyph_info_ligated_and_didnt_multiply rive_hb_glyph_info_ligated_and_didnt_multiply
+#define hb_glyph_info_ligated_internal rive_hb_glyph_info_ligated_internal
+#define hb_glyph_info_multiplied rive_hb_glyph_info_multiplied
+#define hb_glyph_info_set_aat_deleted rive_hb_glyph_info_set_aat_deleted
+#define hb_glyph_info_set_continuation rive_hb_glyph_info_set_continuation
+#define hb_glyph_info_set_general_category rive_hb_glyph_info_set_general_category
+#define hb_glyph_info_set_glyph_props rive_hb_glyph_info_set_glyph_props
+#define hb_glyph_info_set_lig_props_for_component rive_hb_glyph_info_set_lig_props_for_component
+#define hb_glyph_info_set_lig_props_for_ligature rive_hb_glyph_info_set_lig_props_for_ligature
+#define hb_glyph_info_set_lig_props_for_mark rive_hb_glyph_info_set_lig_props_for_mark
+#define hb_glyph_info_set_modified_combining_class rive_hb_glyph_info_set_modified_combining_class
+#define hb_glyph_info_set_unicode_props rive_hb_glyph_info_set_unicode_props
+#define hb_glyph_info_set_unicode_space_fallback_type rive_hb_glyph_info_set_unicode_space_fallback_type
+#define hb_glyph_info_set_variation_selector rive_hb_glyph_info_set_variation_selector
+#define hb_glyph_info_substituted rive_hb_glyph_info_substituted
+#define hb_glyph_info_t rive_hb_glyph_info_t
+#define hb_glyph_info_unhide rive_hb_glyph_info_unhide
+#define hb_glyph_position_t rive_hb_glyph_position_t
+#define hb_grapheme_group_func rive_hb_grapheme_group_func
+#define hb_has rive_hb_has
+#define hb_hash rive_hb_hash
+#define hb_hashmap_t rive_hb_hashmap_t
+#define hb_head_t rive_hb_head_t
+#define hb_identity rive_hb_identity
+#define hb_in_range rive_hb_in_range
+#define hb_in_ranges rive_hb_in_ranges
+#define hb_inc_bimap_t rive_hb_inc_bimap_t
+#define hb_indic_b4 rive_hb_indic_b4
+#define hb_indic_get_categories rive_hb_indic_get_categories
+#define hb_indic_get_categories_index rive_hb_indic_get_categories_index
+#define hb_indic_u8 rive_hb_indic_u8
+#define hb_indic_values rive_hb_indic_values
+#define hb_indic_would_substitute_feature_t rive_hb_indic_would_substitute_feature_t
+#define hb_insert_dotted_circle rive_hb_insert_dotted_circle
+#define hb_invoke rive_hb_invoke
+#define hb_iota rive_hb_iota
+#define hb_iota_iter_t rive_hb_iota_iter_t
+#define hb_iter rive_hb_iter
+#define hb_iter_fallback_mixin_t rive_hb_iter_fallback_mixin_t
+#define hb_iter_t rive_hb_iter_t
+#define hb_language_from_string rive_hb_language_from_string
+#define hb_language_get_default rive_hb_language_get_default
+#define hb_language_impl_t rive_hb_language_impl_t
+#define hb_language_item_t rive_hb_language_item_t
+#define hb_language_matches rive_hb_language_matches
+#define hb_language_to_string rive_hb_language_to_string
+#define hb_latin1_t rive_hb_latin1_t
+#define hb_lazy_loader_t rive_hb_lazy_loader_t
+#define hb_len rive_hb_len
+#define hb_lock_t rive_hb_lock_t
+#define hb_lockable_set_t rive_hb_lockable_set_t
+#define hb_mac_language_map rive_hb_mac_language_map
+#define hb_malloc rive_hb_malloc
+#define hb_map rive_hb_map
 #define hb_map_allocation_successful rive_hb_map_allocation_successful
 #define hb_map_clear rive_hb_map_clear
 #define hb_map_copy rive_hb_map_copy
@@ -731,14 +607,52 @@
 #define hb_map_hash rive_hb_map_hash
 #define hb_map_is_empty rive_hb_map_is_empty
 #define hb_map_is_equal rive_hb_map_is_equal
+#define hb_map_iter_factory_t rive_hb_map_iter_factory_t
+#define hb_map_iter_t rive_hb_map_iter_t
 #define hb_map_keys rive_hb_map_keys
 #define hb_map_next rive_hb_map_next
 #define hb_map_reference rive_hb_map_reference
+#define hb_map_retains_sorting rive_hb_map_retains_sorting
 #define hb_map_set rive_hb_map_set
 #define hb_map_set_user_data rive_hb_map_set_user_data
+#define hb_map_t rive_hb_map_t
 #define hb_map_update rive_hb_map_update
 #define hb_map_values rive_hb_map_values
+#define hb_match rive_hb_match
+#define hb_match_reference rive_hb_match_reference
+#define hb_max rive_hb_max
+#define hb_memcmp rive_hb_memcmp
+#define hb_memcpy rive_hb_memcpy
+#define hb_memset rive_hb_memset
+#define hb_min rive_hb_min
+#define hb_ms_language_map rive_hb_ms_language_map
+#define hb_multimap_t rive_hb_multimap_t
+#define hb_mutex_t rive_hb_mutex_t
+#define hb_next_syllable rive_hb_next_syllable
+#define hb_no_trace_t rive_hb_no_trace_t
+#define hb_none rive_hb_none
+#define hb_nonnull_ptr_t rive_hb_nonnull_ptr_t
+#define hb_not_found_t rive_hb_not_found_t
+#define hb_object_actually_destroy rive_hb_object_actually_destroy
+#define hb_object_create rive_hb_object_create
+#define hb_object_destroy rive_hb_object_destroy
+#define hb_object_fini rive_hb_object_fini
+#define hb_object_get_user_data rive_hb_object_get_user_data
+#define hb_object_header_t rive_hb_object_header_t
+#define hb_object_init rive_hb_object_init
+#define hb_object_is_immutable rive_hb_object_is_immutable
+#define hb_object_is_valid rive_hb_object_is_valid
+#define hb_object_make_immutable rive_hb_object_make_immutable
+#define hb_object_reference rive_hb_object_reference
+#define hb_object_set_user_data rive_hb_object_set_user_data
+#define hb_object_should_destroy rive_hb_object_should_destroy
+#define hb_object_trace rive_hb_object_trace
+#define hb_ot_all_tags_from_script rive_hb_ot_all_tags_from_script
+#define hb_ot_ambiguous_tag_to_language rive_hb_ot_ambiguous_tag_to_language
+#define hb_ot_color_get_svg_document_count rive_hb_ot_color_get_svg_document_count
+#define hb_ot_color_get_svg_document_glyph_range rive_hb_ot_color_get_svg_document_glyph_range
 #define hb_ot_color_glyph_get_layers rive_hb_ot_color_glyph_get_layers
+#define hb_ot_color_glyph_get_svg_document_index rive_hb_ot_color_glyph_get_svg_document_index
 #define hb_ot_color_glyph_has_paint rive_hb_ot_color_glyph_has_paint
 #define hb_ot_color_glyph_reference_png rive_hb_ot_color_glyph_reference_png
 #define hb_ot_color_glyph_reference_svg rive_hb_ot_color_glyph_reference_svg
@@ -747,31 +661,35 @@
 #define hb_ot_color_has_palettes rive_hb_ot_color_has_palettes
 #define hb_ot_color_has_png rive_hb_ot_color_has_png
 #define hb_ot_color_has_svg rive_hb_ot_color_has_svg
+#define hb_ot_color_layer_t rive_hb_ot_color_layer_t
 #define hb_ot_color_palette_color_get_name_id rive_hb_ot_color_palette_color_get_name_id
 #define hb_ot_color_palette_get_colors rive_hb_ot_color_palette_get_colors
 #define hb_ot_color_palette_get_count rive_hb_ot_color_palette_get_count
 #define hb_ot_color_palette_get_flags rive_hb_ot_color_palette_get_flags
 #define hb_ot_color_palette_get_name_id rive_hb_ot_color_palette_get_name_id
-#define hb_ot_metrics_get_position_common rive_hb_ot_metrics_get_position_common
+#define hb_ot_deal_with_variation_selectors rive_hb_ot_deal_with_variation_selectors
+#define hb_ot_draw_glyph_or_fail rive_hb_ot_draw_glyph_or_fail
+#define hb_ot_face_data_t rive_hb_ot_face_data_t
+#define hb_ot_face_t rive_hb_ot_face_t
 #define hb_ot_font_create rive_hb_ot_font_create
+#define hb_ot_font_data_t rive_hb_ot_font_data_t
 #define hb_ot_font_destroy rive_hb_ot_font_destroy
+#define hb_ot_font_funcs_lazy_loader_t rive_hb_ot_font_funcs_lazy_loader_t
+#define hb_ot_font_set_funcs rive_hb_ot_font_set_funcs
+#define hb_ot_font_t rive_hb_ot_font_t
 #define hb_ot_get_font_funcs rive_hb_ot_get_font_funcs
-#define hb_allocate_lig_id rive_hb_allocate_lig_id
-#define hb_glyph_info_is_mark rive_hb_glyph_info_is_mark
-#define hb_glyph_info_get_lig_id rive_hb_glyph_info_get_lig_id
-#define hb_glyph_info_multiplied rive_hb_glyph_info_multiplied
-#define hb_glyph_info_is_ligature rive_hb_glyph_info_is_ligature
-#define hb_glyph_info_get_lig_comp rive_hb_glyph_info_get_lig_comp
-#define hb_glyph_info_is_base_glyph rive_hb_glyph_info_is_base_glyph
-#define hb_ot_layout_set_glyph_props rive_hb_ot_layout_set_glyph_props
-#define hb_glyph_info_clear_lig_props rive_hb_glyph_info_clear_lig_props
-#define hb_buffer_assert_gsubgpos_vars rive_hb_buffer_assert_gsubgpos_vars
-#define hb_glyph_info_ligated_internal rive_hb_glyph_info_ligated_internal
-#define hb_glyph_info_get_lig_num_comps rive_hb_glyph_info_get_lig_num_comps
-#define hb_glyph_info_set_general_category rive_hb_glyph_info_set_general_category
-#define hb_glyph_info_set_lig_props_for_mark rive_hb_glyph_info_set_lig_props_for_mark
-#define hb_glyph_info_set_lig_props_for_ligature rive_hb_glyph_info_set_lig_props_for_ligature
-#define hb_glyph_info_set_lig_props_for_component rive_hb_glyph_info_set_lig_props_for_component
+#define hb_ot_get_font_h_extents rive_hb_ot_get_font_h_extents
+#define hb_ot_get_font_v_extents rive_hb_ot_get_font_v_extents
+#define hb_ot_get_glyph_extents rive_hb_ot_get_glyph_extents
+#define hb_ot_get_glyph_from_name rive_hb_ot_get_glyph_from_name
+#define hb_ot_get_glyph_h_advances rive_hb_ot_get_glyph_h_advances
+#define hb_ot_get_glyph_name rive_hb_ot_get_glyph_name
+#define hb_ot_get_glyph_v_advances rive_hb_ot_get_glyph_v_advances
+#define hb_ot_get_nominal_glyph rive_hb_ot_get_nominal_glyph
+#define hb_ot_get_nominal_glyphs rive_hb_ot_get_nominal_glyphs
+#define hb_ot_get_variation_glyph rive_hb_ot_get_variation_glyph
+#define hb_ot_hide_default_ignorables rive_hb_ot_hide_default_ignorables
+#define hb_ot_language_map_t rive_hb_ot_language_map_t
 #define hb_ot_layout_collect_features rive_hb_ot_layout_collect_features
 #define hb_ot_layout_collect_features_map rive_hb_ot_layout_collect_features_map
 #define hb_ot_layout_collect_lookups rive_hb_ot_layout_collect_lookups
@@ -791,9 +709,14 @@
 #define hb_ot_layout_get_horizontal_baseline_tag_for_script rive_hb_ot_layout_get_horizontal_baseline_tag_for_script
 #define hb_ot_layout_get_ligature_carets rive_hb_ot_layout_get_ligature_carets
 #define hb_ot_layout_get_size_params rive_hb_ot_layout_get_size_params
+#define hb_ot_layout_glyph_props_flags_t rive_hb_ot_layout_glyph_props_flags_t
+#define hb_ot_layout_has_cross_kerning rive_hb_ot_layout_has_cross_kerning
 #define hb_ot_layout_has_glyph_classes rive_hb_ot_layout_has_glyph_classes
+#define hb_ot_layout_has_kerning rive_hb_ot_layout_has_kerning
+#define hb_ot_layout_has_machine_kerning rive_hb_ot_layout_has_machine_kerning
 #define hb_ot_layout_has_positioning rive_hb_ot_layout_has_positioning
 #define hb_ot_layout_has_substitution rive_hb_ot_layout_has_substitution
+#define hb_ot_layout_kern rive_hb_ot_layout_kern
 #define hb_ot_layout_language_find_feature rive_hb_ot_layout_language_find_feature
 #define hb_ot_layout_language_get_feature_indexes rive_hb_ot_layout_language_get_feature_indexes
 #define hb_ot_layout_language_get_feature_tags rive_hb_ot_layout_language_get_feature_tags
@@ -805,26 +728,29 @@
 #define hb_ot_layout_lookup_substitute_closure rive_hb_ot_layout_lookup_substitute_closure
 #define hb_ot_layout_lookup_would_substitute rive_hb_ot_layout_lookup_would_substitute
 #define hb_ot_layout_lookups_substitute_closure rive_hb_ot_layout_lookups_substitute_closure
+#define hb_ot_layout_position_finish_advances rive_hb_ot_layout_position_finish_advances
+#define hb_ot_layout_position_finish_offsets rive_hb_ot_layout_position_finish_offsets
+#define hb_ot_layout_position_start rive_hb_ot_layout_position_start
+#define hb_ot_layout_reverse_graphemes rive_hb_ot_layout_reverse_graphemes
 #define hb_ot_layout_script_find_language rive_hb_ot_layout_script_find_language
 #define hb_ot_layout_script_get_language_tags rive_hb_ot_layout_script_get_language_tags
 #define hb_ot_layout_script_select_language rive_hb_ot_layout_script_select_language
 #define hb_ot_layout_script_select_language2 rive_hb_ot_layout_script_select_language2
+#define hb_ot_layout_set_glyph_props rive_hb_ot_layout_set_glyph_props
+#define hb_ot_layout_substitute_lookup rive_hb_ot_layout_substitute_lookup
+#define hb_ot_layout_substitute_start rive_hb_ot_layout_substitute_start
 #define hb_ot_layout_table_choose_script rive_hb_ot_layout_table_choose_script
+#define hb_ot_layout_table_find_feature rive_hb_ot_layout_table_find_feature
 #define hb_ot_layout_table_find_feature_variations rive_hb_ot_layout_table_find_feature_variations
 #define hb_ot_layout_table_find_script rive_hb_ot_layout_table_find_script
 #define hb_ot_layout_table_get_feature_tags rive_hb_ot_layout_table_get_feature_tags
 #define hb_ot_layout_table_get_lookup_count rive_hb_ot_layout_table_get_lookup_count
 #define hb_ot_layout_table_get_script_tags rive_hb_ot_layout_table_get_script_tags
 #define hb_ot_layout_table_select_script rive_hb_ot_layout_table_select_script
-#define hb_ot_metrics_get_position_with_fallback rive_hb_ot_metrics_get_position_with_fallback
-#define hb_ot_tags_from_script_and_language rive_hb_ot_tags_from_script_and_language
-#define hb_set_add_range rive_hb_set_add_range
-#define hb_set_create rive_hb_set_create
-#define hb_set_destroy rive_hb_set_destroy
-#define hb_set_get_empty rive_hb_set_get_empty
-#define hb_set_get_user_data rive_hb_set_get_user_data
-#define hb_set_reference rive_hb_set_reference
-#define hb_set_set_user_data rive_hb_set_set_user_data
+#define hb_ot_map_builder_t rive_hb_ot_map_builder_t
+#define hb_ot_map_feature_flags_t rive_hb_ot_map_feature_flags_t
+#define hb_ot_map_glyphs_fast rive_hb_ot_map_glyphs_fast
+#define hb_ot_map_t rive_hb_ot_map_t
 #define hb_ot_math_get_constant rive_hb_ot_math_get_constant
 #define hb_ot_math_get_glyph_assembly rive_hb_ot_math_get_glyph_assembly
 #define hb_ot_math_get_glyph_italics_correction rive_hb_ot_math_get_glyph_italics_correction
@@ -833,60 +759,73 @@
 #define hb_ot_math_get_glyph_top_accent_attachment rive_hb_ot_math_get_glyph_top_accent_attachment
 #define hb_ot_math_get_glyph_variants rive_hb_ot_math_get_glyph_variants
 #define hb_ot_math_get_min_connector_overlap rive_hb_ot_math_get_min_connector_overlap
+#define hb_ot_math_glyph_part_t rive_hb_ot_math_glyph_part_t
+#define hb_ot_math_glyph_variant_t rive_hb_ot_math_glyph_variant_t
 #define hb_ot_math_has_data rive_hb_ot_math_has_data
 #define hb_ot_math_is_glyph_extended_shape rive_hb_ot_math_is_glyph_extended_shape
+#define hb_ot_math_kern_entry_t rive_hb_ot_math_kern_entry_t
+#define hb_ot_math_kern_t rive_hb_ot_math_kern_t
 #define hb_ot_meta_get_entry_tags rive_hb_ot_meta_get_entry_tags
 #define hb_ot_meta_reference_entry rive_hb_ot_meta_reference_entry
+#define hb_ot_meta_tag_t rive_hb_ot_meta_tag_t
 #define hb_ot_metrics_get_position rive_hb_ot_metrics_get_position
+#define hb_ot_metrics_get_position_common rive_hb_ot_metrics_get_position_common
+#define hb_ot_metrics_get_position_with_fallback rive_hb_ot_metrics_get_position_with_fallback
 #define hb_ot_metrics_get_variation rive_hb_ot_metrics_get_variation
 #define hb_ot_metrics_get_x_variation rive_hb_ot_metrics_get_x_variation
 #define hb_ot_metrics_get_y_variation rive_hb_ot_metrics_get_y_variation
-#define hb_ot_name_language_for_ms_code rive_hb_ot_name_language_for_ms_code
-#define hb_ot_name_language_for_mac_code rive_hb_ot_name_language_for_mac_code
+#define hb_ot_metrics_tag_t rive_hb_ot_metrics_tag_t
+#define hb_ot_name_entry_t rive_hb_ot_name_entry_t
+#define hb_ot_name_get_utf rive_hb_ot_name_get_utf
 #define hb_ot_name_get_utf16 rive_hb_ot_name_get_utf16
 #define hb_ot_name_get_utf32 rive_hb_ot_name_get_utf32
 #define hb_ot_name_get_utf8 rive_hb_ot_name_get_utf8
+#define hb_ot_name_language_for rive_hb_ot_name_language_for
+#define hb_ot_name_language_for_mac_code rive_hb_ot_name_language_for_mac_code
+#define hb_ot_name_language_for_ms_code rive_hb_ot_name_language_for_ms_code
 #define hb_ot_name_list_names rive_hb_ot_name_list_names
+#define hb_ot_new_tag_from_script rive_hb_ot_new_tag_from_script
+#define hb_ot_new_tag_to_script rive_hb_ot_new_tag_to_script
+#define hb_ot_old_tag_from_script rive_hb_ot_old_tag_from_script
+#define hb_ot_old_tag_to_script rive_hb_ot_old_tag_to_script
+#define hb_ot_paint_glyph_or_fail rive_hb_ot_paint_glyph_or_fail
+#define hb_ot_position rive_hb_ot_position
+#define hb_ot_position_default rive_hb_ot_position_default
+#define hb_ot_position_plan rive_hb_ot_position_plan
+#define hb_ot_rotate_chars rive_hb_ot_rotate_chars
+#define hb_ot_shape_collect_features rive_hb_ot_shape_collect_features
 #define hb_ot_shape_fallback_kern rive_hb_ot_shape_fallback_kern
-#define hb_ot_shape_fallback_spaces rive_hb_ot_shape_fallback_spaces
+#define hb_ot_shape_fallback_kern_driver_t rive_hb_ot_shape_fallback_kern_driver_t
 #define hb_ot_shape_fallback_mark_position rive_hb_ot_shape_fallback_mark_position
 #define hb_ot_shape_fallback_mark_position_recategorize_marks rive_hb_ot_shape_fallback_mark_position_recategorize_marks
-#define hb_glyph_info_ligated rive_hb_glyph_info_ligated
-#define hb_glyph_info_is_unicode_mark rive_hb_glyph_info_is_unicode_mark
-#define hb_glyph_info_is_unicode_space rive_hb_glyph_info_is_unicode_space
-#define hb_glyph_info_get_modified_combining_class rive_hb_glyph_info_get_modified_combining_class
-#define hb_glyph_info_set_modified_combining_class rive_hb_glyph_info_set_modified_combining_class
-#define hb_glyph_info_get_unicode_space_fallback_type rive_hb_glyph_info_get_unicode_space_fallback_type
-#define hb_ot_shape_normalize rive_hb_ot_shape_normalize
-#define hb_glyph_info_unhide rive_hb_glyph_info_unhide
-#define hb_buffer_assert_unicode_vars rive_hb_buffer_assert_unicode_vars
-#define hb_glyph_info_set_unicode_props rive_hb_glyph_info_set_unicode_props
-#define hb_glyph_info_set_unicode_space_fallback_type rive_hb_glyph_info_set_unicode_space_fallback_type
-#define hb_unicode_is_emoji_Extended_Pictographic rive_hb_unicode_is_emoji_Extended_Pictographic
-#define hb_apply_morx rive_hb_apply_morx
-#define hb_glyph_info_set_continuation rive_hb_glyph_info_set_continuation
-#define hb_ot_layout_reverse_graphemes rive_hb_ot_layout_reverse_graphemes
-#define hb_buffer_allocate_unicode_vars rive_hb_buffer_allocate_unicode_vars
-#define hb_buffer_allocate_gsubgpos_vars rive_hb_buffer_allocate_gsubgpos_vars
-#define hb_buffer_deallocate_unicode_vars rive_hb_buffer_deallocate_unicode_vars
-#define hb_buffer_deallocate_gsubgpos_vars rive_hb_buffer_deallocate_gsubgpos_vars
-#define hb_codepoint_is_regional_indicator rive_hb_codepoint_is_regional_indicator
-#define hb_glyph_info_is_default_ignorable rive_hb_glyph_info_is_default_ignorable
+#define hb_ot_shape_fallback_spaces rive_hb_ot_shape_fallback_spaces
 #define hb_ot_shape_glyphs_closure rive_hb_ot_shape_glyphs_closure
+#define hb_ot_shape_initialize_masks rive_hb_ot_shape_initialize_masks
+#define hb_ot_shape_internal rive_hb_ot_shape_internal
+#define hb_ot_shape_normalize rive_hb_ot_shape_normalize
+#define hb_ot_shape_normalize_context_t rive_hb_ot_shape_normalize_context_t
 #define hb_ot_shape_plan_collect_lookups rive_hb_ot_shape_plan_collect_lookups
-#define hb_shape_plan_create_cached rive_hb_shape_plan_create_cached
-#define hb_preprocess_text_vowel_constraints rive_hb_preprocess_text_vowel_constraints
-#define hb_next_syllable rive_hb_next_syllable
-#define hb_glyph_info_ligated_and_didnt_multiply rive_hb_glyph_info_ligated_and_didnt_multiply
-#define hb_glyph_info_clear_ligated_and_multiplied rive_hb_glyph_info_clear_ligated_and_multiplied
-#define hb_clear_substitution_flags rive_hb_clear_substitution_flags
-#define hb_glyph_info_clear_substituted rive_hb_glyph_info_clear_substituted
-#define hb_glyph_info_reset_continuation rive_hb_glyph_info_reset_continuation
+#define hb_ot_shape_plan_get_feature_tags rive_hb_ot_shape_plan_get_feature_tags
+#define hb_ot_shape_plan_key_t rive_hb_ot_shape_plan_key_t
+#define hb_ot_shape_plan_t rive_hb_ot_shape_plan_t
+#define hb_ot_shape_planner_t rive_hb_ot_shape_planner_t
+#define hb_ot_shape_setup_masks rive_hb_ot_shape_setup_masks
+#define hb_ot_shape_setup_masks_fraction rive_hb_ot_shape_setup_masks_fraction
+#define hb_ot_shaper_categorize rive_hb_ot_shaper_categorize
+#define hb_ot_substitute_default rive_hb_ot_substitute_default
+#define hb_ot_substitute_plan rive_hb_ot_substitute_plan
+#define hb_ot_substitute_post rive_hb_ot_substitute_post
+#define hb_ot_substitute_pre rive_hb_ot_substitute_pre
 #define hb_ot_tag_from_language rive_hb_ot_tag_from_language
 #define hb_ot_tag_to_language rive_hb_ot_tag_to_language
 #define hb_ot_tag_to_script rive_hb_ot_tag_to_script
+#define hb_ot_tags_from_complex_language rive_hb_ot_tags_from_complex_language
+#define hb_ot_tags_from_language rive_hb_ot_tags_from_language
 #define hb_ot_tags_from_script rive_hb_ot_tags_from_script
+#define hb_ot_tags_from_script_and_language rive_hb_ot_tags_from_script_and_language
 #define hb_ot_tags_to_script_and_language rive_hb_ot_tags_to_script_and_language
+#define hb_ot_var_axis_info_t rive_hb_ot_var_axis_info_t
+#define hb_ot_var_axis_t rive_hb_ot_var_axis_t
 #define hb_ot_var_find_axis rive_hb_ot_var_find_axis
 #define hb_ot_var_find_axis_info rive_hb_ot_var_find_axis_info
 #define hb_ot_var_get_axes rive_hb_ot_var_get_axes
@@ -894,59 +833,169 @@
 #define hb_ot_var_get_axis_infos rive_hb_ot_var_get_axis_infos
 #define hb_ot_var_get_named_instance_count rive_hb_ot_var_get_named_instance_count
 #define hb_ot_var_has_data rive_hb_ot_var_has_data
+#define hb_ot_var_named_instance_get_design_coords rive_hb_ot_var_named_instance_get_design_coords
 #define hb_ot_var_named_instance_get_postscript_name_id rive_hb_ot_var_named_instance_get_postscript_name_id
 #define hb_ot_var_named_instance_get_subfamily_name_id rive_hb_ot_var_named_instance_get_subfamily_name_id
+#define hb_ot_var_normalize_coords rive_hb_ot_var_normalize_coords
 #define hb_ot_var_normalize_variations rive_hb_ot_var_normalize_variations
+#define hb_ot_zero_width_default_ignorables rive_hb_ot_zero_width_default_ignorables
+#define hb_outline_point_t rive_hb_outline_point_t
+#define hb_outline_recording_pen_close_path rive_hb_outline_recording_pen_close_path
+#define hb_outline_recording_pen_cubic_to rive_hb_outline_recording_pen_cubic_to
+#define hb_outline_recording_pen_funcs_lazy_loader_t rive_hb_outline_recording_pen_funcs_lazy_loader_t
+#define hb_outline_recording_pen_get_funcs rive_hb_outline_recording_pen_get_funcs
+#define hb_outline_recording_pen_line_to rive_hb_outline_recording_pen_line_to
+#define hb_outline_recording_pen_move_to rive_hb_outline_recording_pen_move_to
+#define hb_outline_recording_pen_quadratic_to rive_hb_outline_recording_pen_quadratic_to
+#define hb_outline_t rive_hb_outline_t
+#define hb_outline_vector_t rive_hb_outline_vector_t
+#define hb_paint_bounded_context_t rive_hb_paint_bounded_context_t
+#define hb_paint_bounded_funcs_lazy_loader_t rive_hb_paint_bounded_funcs_lazy_loader_t
+#define hb_paint_bounded_get_funcs rive_hb_paint_bounded_get_funcs
+#define hb_paint_bounded_paint_color rive_hb_paint_bounded_paint_color
+#define hb_paint_bounded_paint_image rive_hb_paint_bounded_paint_image
+#define hb_paint_bounded_paint_linear_gradient rive_hb_paint_bounded_paint_linear_gradient
+#define hb_paint_bounded_paint_radial_gradient rive_hb_paint_bounded_paint_radial_gradient
+#define hb_paint_bounded_paint_sweep_gradient rive_hb_paint_bounded_paint_sweep_gradient
+#define hb_paint_bounded_pop_clip rive_hb_paint_bounded_pop_clip
+#define hb_paint_bounded_pop_group rive_hb_paint_bounded_pop_group
+#define hb_paint_bounded_push_clip_glyph rive_hb_paint_bounded_push_clip_glyph
+#define hb_paint_bounded_push_clip_rectangle rive_hb_paint_bounded_push_clip_rectangle
+#define hb_paint_bounded_push_group rive_hb_paint_bounded_push_group
+#define hb_paint_color rive_hb_paint_color
+#define hb_paint_color_glyph rive_hb_paint_color_glyph
+#define hb_paint_color_glyph_nil rive_hb_paint_color_glyph_nil
+#define hb_paint_color_nil rive_hb_paint_color_nil
+#define hb_paint_composite_mode_t rive_hb_paint_composite_mode_t
+#define hb_paint_custom_palette_color rive_hb_paint_custom_palette_color
+#define hb_paint_custom_palette_color_nil rive_hb_paint_custom_palette_color_nil
+#define hb_paint_extents_context_t rive_hb_paint_extents_context_t
+#define hb_paint_extents_funcs_lazy_loader_t rive_hb_paint_extents_funcs_lazy_loader_t
+#define hb_paint_extents_get_funcs rive_hb_paint_extents_get_funcs
+#define hb_paint_extents_paint_color rive_hb_paint_extents_paint_color
+#define hb_paint_extents_paint_image rive_hb_paint_extents_paint_image
+#define hb_paint_extents_paint_linear_gradient rive_hb_paint_extents_paint_linear_gradient
+#define hb_paint_extents_paint_radial_gradient rive_hb_paint_extents_paint_radial_gradient
+#define hb_paint_extents_paint_sweep_gradient rive_hb_paint_extents_paint_sweep_gradient
+#define hb_paint_extents_pop_clip rive_hb_paint_extents_pop_clip
+#define hb_paint_extents_pop_group rive_hb_paint_extents_pop_group
+#define hb_paint_extents_pop_transform rive_hb_paint_extents_pop_transform
+#define hb_paint_extents_push_clip_glyph rive_hb_paint_extents_push_clip_glyph
+#define hb_paint_extents_push_clip_rectangle rive_hb_paint_extents_push_clip_rectangle
+#define hb_paint_extents_push_group rive_hb_paint_extents_push_group
+#define hb_paint_extents_push_transform rive_hb_paint_extents_push_transform
 #define hb_paint_funcs_create rive_hb_paint_funcs_create
 #define hb_paint_funcs_destroy rive_hb_paint_funcs_destroy
 #define hb_paint_funcs_get_empty rive_hb_paint_funcs_get_empty
+#define hb_paint_funcs_get_user_data rive_hb_paint_funcs_get_user_data
+#define hb_paint_funcs_is_immutable rive_hb_paint_funcs_is_immutable
+#define hb_paint_funcs_lazy_loader_t rive_hb_paint_funcs_lazy_loader_t
 #define hb_paint_funcs_make_immutable rive_hb_paint_funcs_make_immutable
+#define hb_paint_funcs_reference rive_hb_paint_funcs_reference
 #define hb_paint_funcs_set_color_func rive_hb_paint_funcs_set_color_func
+#define hb_paint_funcs_set_color_glyph_func rive_hb_paint_funcs_set_color_glyph_func
+#define hb_paint_funcs_set_custom_palette_color_func rive_hb_paint_funcs_set_custom_palette_color_func
 #define hb_paint_funcs_set_image_func rive_hb_paint_funcs_set_image_func
 #define hb_paint_funcs_set_linear_gradient_func rive_hb_paint_funcs_set_linear_gradient_func
+#define hb_paint_funcs_set_middle rive_hb_paint_funcs_set_middle
 #define hb_paint_funcs_set_pop_clip_func rive_hb_paint_funcs_set_pop_clip_func
 #define hb_paint_funcs_set_pop_group_func rive_hb_paint_funcs_set_pop_group_func
 #define hb_paint_funcs_set_pop_transform_func rive_hb_paint_funcs_set_pop_transform_func
+#define hb_paint_funcs_set_preamble rive_hb_paint_funcs_set_preamble
 #define hb_paint_funcs_set_push_clip_glyph_func rive_hb_paint_funcs_set_push_clip_glyph_func
 #define hb_paint_funcs_set_push_clip_rectangle_func rive_hb_paint_funcs_set_push_clip_rectangle_func
 #define hb_paint_funcs_set_push_group_func rive_hb_paint_funcs_set_push_group_func
 #define hb_paint_funcs_set_push_transform_func rive_hb_paint_funcs_set_push_transform_func
 #define hb_paint_funcs_set_radial_gradient_func rive_hb_paint_funcs_set_radial_gradient_func
 #define hb_paint_funcs_set_sweep_gradient_func rive_hb_paint_funcs_set_sweep_gradient_func
-#define hb_paint_funcs_set_middle rive_hb_paint_funcs_set_middle
-#define hb_paint_funcs_set_preamble rive_hb_paint_funcs_set_preamble
-#define hb_color_line_get_color_stops rive_hb_color_line_get_color_stops
-#define hb_color_line_get_extend rive_hb_color_line_get_extend
-#define hb_paint_color rive_hb_paint_color
-#define hb_paint_color_glyph rive_hb_paint_color_glyph
-#define hb_paint_custom_palette_color rive_hb_paint_custom_palette_color
-#define hb_paint_funcs_get_user_data rive_hb_paint_funcs_get_user_data
-#define hb_paint_funcs_is_immutable rive_hb_paint_funcs_is_immutable
-#define hb_paint_funcs_reference rive_hb_paint_funcs_reference
-#define hb_paint_funcs_set_color_glyph_func rive_hb_paint_funcs_set_color_glyph_func
-#define hb_paint_funcs_set_custom_palette_color_func rive_hb_paint_funcs_set_custom_palette_color_func
 #define hb_paint_funcs_set_user_data rive_hb_paint_funcs_set_user_data
+#define hb_paint_funcs_t rive_hb_paint_funcs_t
 #define hb_paint_image rive_hb_paint_image
+#define hb_paint_image_nil rive_hb_paint_image_nil
 #define hb_paint_linear_gradient rive_hb_paint_linear_gradient
+#define hb_paint_linear_gradient_nil rive_hb_paint_linear_gradient_nil
 #define hb_paint_pop_clip rive_hb_paint_pop_clip
+#define hb_paint_pop_clip_nil rive_hb_paint_pop_clip_nil
 #define hb_paint_pop_group rive_hb_paint_pop_group
+#define hb_paint_pop_group_nil rive_hb_paint_pop_group_nil
 #define hb_paint_pop_transform rive_hb_paint_pop_transform
+#define hb_paint_pop_transform_nil rive_hb_paint_pop_transform_nil
 #define hb_paint_push_clip_glyph rive_hb_paint_push_clip_glyph
+#define hb_paint_push_clip_glyph_nil rive_hb_paint_push_clip_glyph_nil
 #define hb_paint_push_clip_rectangle rive_hb_paint_push_clip_rectangle
+#define hb_paint_push_clip_rectangle_nil rive_hb_paint_push_clip_rectangle_nil
+#define hb_paint_push_font_transform rive_hb_paint_push_font_transform
 #define hb_paint_push_group rive_hb_paint_push_group
+#define hb_paint_push_group_nil rive_hb_paint_push_group_nil
+#define hb_paint_push_inverse_font_transform rive_hb_paint_push_inverse_font_transform
 #define hb_paint_push_transform rive_hb_paint_push_transform
+#define hb_paint_push_transform_nil rive_hb_paint_push_transform_nil
 #define hb_paint_radial_gradient rive_hb_paint_radial_gradient
+#define hb_paint_radial_gradient_nil rive_hb_paint_radial_gradient_nil
 #define hb_paint_sweep_gradient rive_hb_paint_sweep_gradient
+#define hb_paint_sweep_gradient_nil rive_hb_paint_sweep_gradient_nil
+#define hb_pair rive_hb_pair
+#define hb_pair_t rive_hb_pair_t
+#define hb_parse_double rive_hb_parse_double
+#define hb_parse_int rive_hb_parse_int
+#define hb_parse_uint rive_hb_parse_uint
+#define hb_partial rive_hb_partial
+#define hb_partial_t rive_hb_partial_t
+#define hb_plan_subset_cff_fdselect rive_hb_plan_subset_cff_fdselect
+#define hb_popcount rive_hb_popcount
+#define hb_popcount8 rive_hb_popcount8
+#define hb_position_single_dispatch_t rive_hb_position_single_dispatch_t
+#define hb_preprocess_text_vowel_constraints rive_hb_preprocess_text_vowel_constraints
+#define hb_priority rive_hb_priority
+#define hb_priority_queue_t rive_hb_priority_queue_t
+#define hb_propagate_flags rive_hb_propagate_flags
+#define hb_qsort rive_hb_qsort
+#define hb_range rive_hb_range
+#define hb_range_iter_t rive_hb_range_iter_t
+#define hb_ratio_to_angle rive_hb_ratio_to_angle
+#define hb_realloc rive_hb_realloc
+#define hb_reduce rive_hb_reduce
+#define hb_reduce_t rive_hb_reduce_t
+#define hb_reference_count_t rive_hb_reference_count_t
+#define hb_reference_wrapper rive_hb_reference_wrapper
+#define hb_repeat rive_hb_repeat
+#define hb_repeat_iter_t rive_hb_repeat_iter_t
+#define hb_resolve_graph_overflows rive_hb_resolve_graph_overflows
+#define hb_resolve_overflows rive_hb_resolve_overflows
+#define hb_ridentity rive_hb_ridentity
+#define hb_roundf rive_hb_roundf
+#define hb_sanitize_context_t rive_hb_sanitize_context_t
+#define hb_sanitize_with_object_t rive_hb_sanitize_with_object_t
+#define hb_script_from_iso15924_tag rive_hb_script_from_iso15924_tag
+#define hb_script_from_string rive_hb_script_from_string
+#define hb_script_get_horizontal_direction rive_hb_script_get_horizontal_direction
+#define hb_script_t rive_hb_script_t
+#define hb_script_to_iso15924_tag rive_hb_script_to_iso15924_tag
+#define hb_second rive_hb_second
+#define hb_segment_properties_equal rive_hb_segment_properties_equal
+#define hb_segment_properties_hash rive_hb_segment_properties_hash
+#define hb_segment_properties_overlay rive_hb_segment_properties_overlay
+#define hb_segment_properties_t rive_hb_segment_properties_t
+#define hb_serialize_cff_fdselect rive_hb_serialize_cff_fdselect
+#define hb_serialize_context_t rive_hb_serialize_context_t
+#define hb_serialize_error_t rive_hb_serialize_error_t
 #define hb_set_add rive_hb_set_add
+#define hb_set_add_range rive_hb_set_add_range
 #define hb_set_add_sorted_array rive_hb_set_add_sorted_array
 #define hb_set_allocation_successful rive_hb_set_allocation_successful
 #define hb_set_clear rive_hb_set_clear
 #define hb_set_copy rive_hb_set_copy
+#define hb_set_create rive_hb_set_create
 #define hb_set_del rive_hb_set_del
 #define hb_set_del_range rive_hb_set_del_range
+#define hb_set_destroy rive_hb_set_destroy
+#define hb_set_digest_shifts rive_hb_set_digest_shifts
+#define hb_set_digest_t rive_hb_set_digest_t
+#define hb_set_get_empty rive_hb_set_get_empty
 #define hb_set_get_max rive_hb_set_get_max
 #define hb_set_get_min rive_hb_set_get_min
 #define hb_set_get_population rive_hb_set_get_population
+#define hb_set_get_user_data rive_hb_set_get_user_data
 #define hb_set_has rive_hb_set_has
 #define hb_set_hash rive_hb_set_hash
 #define hb_set_intersect rive_hb_set_intersect
@@ -960,144 +1009,192 @@
 #define hb_set_next_range rive_hb_set_next_range
 #define hb_set_previous rive_hb_set_previous
 #define hb_set_previous_range rive_hb_set_previous_range
+#define hb_set_reference rive_hb_set_reference
 #define hb_set_set rive_hb_set_set
+#define hb_set_set_user_data rive_hb_set_set_user_data
 #define hb_set_subtract rive_hb_set_subtract
 #define hb_set_symmetric_difference rive_hb_set_symmetric_difference
+#define hb_set_t rive_hb_set_t
+#define hb_set_unicode_props rive_hb_set_unicode_props
 #define hb_set_union rive_hb_set_union
-#define hb_shapers_get rive_hb_shapers_get
-#define hb_shape_plan_execute_internal rive_hb_shape_plan_execute_internal
+#define hb_shape rive_hb_shape
+#define hb_shape_full rive_hb_shape_full
+#define hb_shape_list_shapers rive_hb_shape_list_shapers
 #define hb_shape_plan_create rive_hb_shape_plan_create
 #define hb_shape_plan_create2 rive_hb_shape_plan_create2
+#define hb_shape_plan_create_cached rive_hb_shape_plan_create_cached
 #define hb_shape_plan_create_cached2 rive_hb_shape_plan_create_cached2
+#define hb_shape_plan_destroy rive_hb_shape_plan_destroy
 #define hb_shape_plan_execute rive_hb_shape_plan_execute
+#define hb_shape_plan_execute_internal rive_hb_shape_plan_execute_internal
 #define hb_shape_plan_get_empty rive_hb_shape_plan_get_empty
 #define hb_shape_plan_get_shaper rive_hb_shape_plan_get_shaper
 #define hb_shape_plan_get_user_data rive_hb_shape_plan_get_user_data
+#define hb_shape_plan_key_t rive_hb_shape_plan_key_t
 #define hb_shape_plan_reference rive_hb_shape_plan_reference
 #define hb_shape_plan_set_user_data rive_hb_shape_plan_set_user_data
-#define hb_shape rive_hb_shape
-#define hb_shape_list_shapers rive_hb_shape_list_shapers
-#define hb_all_shapers rive_hb_all_shapers
-#define hb_ms_language_map rive_hb_ms_language_map
-#define hb_mac_language_map rive_hb_mac_language_map
-#define hb_ot_name_language_for rive_hb_ot_name_language_for
+#define hb_shape_plan_t rive_hb_shape_plan_t
+#define hb_shaper_entry_t rive_hb_shaper_entry_t
+#define hb_shaper_lazy_loader_t rive_hb_shaper_lazy_loader_t
+#define hb_shaper_list_lazy_loader_t rive_hb_shaper_list_lazy_loader_t
+#define hb_shaper_object_dataset_t rive_hb_shaper_object_dataset_t
+#define hb_shapers_get rive_hb_shapers_get
+#define hb_shapers_lazy_loader_t rive_hb_shapers_lazy_loader_t
+#define hb_sincos rive_hb_sincos
+#define hb_sink rive_hb_sink
+#define hb_sink_t rive_hb_sink_t
+#define hb_sorted_array rive_hb_sorted_array
+#define hb_sorted_array_t rive_hb_sorted_array_t
+#define hb_sparseset_t rive_hb_sparseset_t
+#define hb_stable_sort rive_hb_stable_sort
+#define hb_style_get_value rive_hb_style_get_value
+#define hb_style_tag_t rive_hb_style_tag_t
+#define hb_subset_accelerator_t rive_hb_subset_accelerator_t
+#define hb_subset_axis_range_from_string rive_hb_subset_axis_range_from_string
+#define hb_subset_axis_range_to_string rive_hb_subset_axis_range_to_string
+#define hb_subset_context_t rive_hb_subset_context_t
+#define hb_subset_estimate_table_size rive_hb_subset_estimate_table_size
+#define hb_subset_flags_t rive_hb_subset_flags_t
 #define hb_subset_input_create_or_fail rive_hb_subset_input_create_or_fail
 #define hb_subset_input_destroy rive_hb_subset_input_destroy
+#define hb_subset_input_get_axis_range rive_hb_subset_input_get_axis_range
 #define hb_subset_input_get_flags rive_hb_subset_input_get_flags
 #define hb_subset_input_get_user_data rive_hb_subset_input_get_user_data
 #define hb_subset_input_glyph_set rive_hb_subset_input_glyph_set
 #define hb_subset_input_keep_everything rive_hb_subset_input_keep_everything
 #define hb_subset_input_old_to_new_glyph_mapping rive_hb_subset_input_old_to_new_glyph_mapping
+#define hb_subset_input_pin_all_axes_to_default rive_hb_subset_input_pin_all_axes_to_default
 #define hb_subset_input_pin_axis_location rive_hb_subset_input_pin_axis_location
 #define hb_subset_input_pin_axis_to_default rive_hb_subset_input_pin_axis_to_default
 #define hb_subset_input_reference rive_hb_subset_input_reference
 #define hb_subset_input_set rive_hb_subset_input_set
+#define hb_subset_input_set_axis_range rive_hb_subset_input_set_axis_range
 #define hb_subset_input_set_flags rive_hb_subset_input_set_flags
 #define hb_subset_input_set_user_data rive_hb_subset_input_set_user_data
+#define hb_subset_input_t rive_hb_subset_input_t
 #define hb_subset_input_unicode_set rive_hb_subset_input_unicode_set
 #define hb_subset_or_fail rive_hb_subset_or_fail
-#define hb_subset_preprocess rive_hb_subset_preprocess
-#define hb_face_builder_create rive_hb_face_builder_create
 #define hb_subset_plan_create_or_fail rive_hb_subset_plan_create_or_fail
 #define hb_subset_plan_destroy rive_hb_subset_plan_destroy
+#define hb_subset_plan_execute_or_fail rive_hb_subset_plan_execute_or_fail
 #define hb_subset_plan_get_user_data rive_hb_subset_plan_get_user_data
 #define hb_subset_plan_new_to_old_glyph_mapping rive_hb_subset_plan_new_to_old_glyph_mapping
 #define hb_subset_plan_old_to_new_glyph_mapping rive_hb_subset_plan_old_to_new_glyph_mapping
 #define hb_subset_plan_reference rive_hb_subset_plan_reference
 #define hb_subset_plan_set_user_data rive_hb_subset_plan_set_user_data
+#define hb_subset_plan_t rive_hb_subset_plan_t
 #define hb_subset_plan_unicode_to_old_glyph_mapping rive_hb_subset_plan_unicode_to_old_glyph_mapping
-#define hb_debug rive_hb_debug
-#define hb_face_builder_add_table rive_hb_face_builder_add_table
-#define hb_subset_plan_execute_or_fail rive_hb_subset_plan_execute_or_fail
+#define hb_subset_preprocess rive_hb_subset_preprocess
+#define hb_subset_repack rive_hb_subset_repack
+#define hb_subset_serialize_object_t rive_hb_subset_serialize_object_t
+#define hb_subset_serialize_or_fail rive_hb_subset_serialize_or_fail
+#define hb_subset_table rive_hb_subset_table
+#define hb_subset_table_cff rive_hb_subset_table_cff
+#define hb_subset_table_color rive_hb_subset_table_color
+#define hb_subset_table_layout rive_hb_subset_table_layout
+#define hb_subset_table_other rive_hb_subset_table_other
+#define hb_subset_table_passthrough rive_hb_subset_table_passthrough
+#define hb_subset_table_try rive_hb_subset_table_try
+#define hb_subset_table_var rive_hb_subset_table_var
+#define hb_swap rive_hb_swap
+#define hb_syllabic_clear_var rive_hb_syllabic_clear_var
+#define hb_syllabic_insert_dotted_circles rive_hb_syllabic_insert_dotted_circles
+#define hb_synthesize_glyph_classes rive_hb_synthesize_glyph_classes
+#define hb_table_lazy_loader_t rive_hb_table_lazy_loader_t
+#define hb_tag_from_string rive_hb_tag_from_string
+#define hb_tag_to_string rive_hb_tag_to_string
+#define hb_take rive_hb_take
+#define hb_trampoline_t rive_hb_trampoline_t
+#define hb_transform_t rive_hb_transform_t
 #define hb_ucd_b4 rive_hb_ucd_b4
-#define hb_ucd_dm rive_hb_ucd_dm
-#define hb_ucd_gc rive_hb_ucd_gc
-#define hb_ucd_sc rive_hb_ucd_sc
-#define hb_ucd_u8 rive_hb_ucd_u8
 #define hb_ucd_bmg rive_hb_ucd_bmg
 #define hb_ucd_ccc rive_hb_ucd_ccc
-#define hb_ucd_i16 rive_hb_ucd_i16
-#define hb_ucd_u16 rive_hb_ucd_u16
-#define hb_ucd_sc_map rive_hb_ucd_sc_map
+#define hb_ucd_combining_class rive_hb_ucd_combining_class
+#define hb_ucd_compose rive_hb_ucd_compose
+#define hb_ucd_compose_hangul rive_hb_ucd_compose_hangul
+#define hb_ucd_decompose rive_hb_ucd_decompose
+#define hb_ucd_decompose_hangul rive_hb_ucd_decompose_hangul
+#define hb_ucd_dm rive_hb_ucd_dm
 #define hb_ucd_dm1_p0_map rive_hb_ucd_dm1_p0_map
 #define hb_ucd_dm1_p2_map rive_hb_ucd_dm1_p2_map
 #define hb_ucd_dm2_u32_map rive_hb_ucd_dm2_u32_map
 #define hb_ucd_dm2_u64_map rive_hb_ucd_dm2_u64_map
-#define hb_ucd_compose_hangul rive_hb_ucd_compose_hangul
-#define hb_ucd_decompose_hangul rive_hb_ucd_decompose_hangul
+#define hb_ucd_gc rive_hb_ucd_gc
+#define hb_ucd_general_category rive_hb_ucd_general_category
 #define hb_ucd_get_unicode_funcs rive_hb_ucd_get_unicode_funcs
-#define hb_unicode_funcs_create rive_hb_unicode_funcs_create
-#define hb_unicode_funcs_get_empty rive_hb_unicode_funcs_get_empty
-#define hb_unicode_funcs_make_immutable rive_hb_unicode_funcs_make_immutable
-#define hb_unicode_funcs_set_combining_class_func rive_hb_unicode_funcs_set_combining_class_func
-#define hb_unicode_funcs_set_compose_func rive_hb_unicode_funcs_set_compose_func
-#define hb_unicode_funcs_set_decompose_func rive_hb_unicode_funcs_set_decompose_func
-#define hb_unicode_funcs_set_general_category_func rive_hb_unicode_funcs_set_general_category_func
-#define hb_unicode_funcs_set_mirroring_func rive_hb_unicode_funcs_set_mirroring_func
-#define hb_unicode_funcs_set_script_func rive_hb_unicode_funcs_set_script_func
-#define hb_emoji_b1 rive_hb_emoji_b1
-#define hb_emoji_b4 rive_hb_emoji_b4
-#define hb_emoji_u8 rive_hb_emoji_u8
-#define hb_emoji_is_Extended_Pictographic rive_hb_emoji_is_Extended_Pictographic
+#define hb_ucd_i16 rive_hb_ucd_i16
+#define hb_ucd_mirroring rive_hb_ucd_mirroring
+#define hb_ucd_sc rive_hb_ucd_sc
+#define hb_ucd_sc_map rive_hb_ucd_sc_map
+#define hb_ucd_script rive_hb_ucd_script
+#define hb_ucd_u16 rive_hb_ucd_u16
+#define hb_ucd_u8 rive_hb_ucd_u8
+#define hb_ucd_unicode_funcs_lazy_loader_t rive_hb_ucd_unicode_funcs_lazy_loader_t
 #define hb_unicode_combining_class rive_hb_unicode_combining_class
+#define hb_unicode_combining_class_nil rive_hb_unicode_combining_class_nil
 #define hb_unicode_compose rive_hb_unicode_compose
+#define hb_unicode_compose_nil rive_hb_unicode_compose_nil
 #define hb_unicode_decompose rive_hb_unicode_decompose
 #define hb_unicode_decompose_compatibility rive_hb_unicode_decompose_compatibility
+#define hb_unicode_decompose_compatibility_nil rive_hb_unicode_decompose_compatibility_nil
+#define hb_unicode_decompose_nil rive_hb_unicode_decompose_nil
 #define hb_unicode_eastasian_width rive_hb_unicode_eastasian_width
+#define hb_unicode_eastasian_width_nil rive_hb_unicode_eastasian_width_nil
+#define hb_unicode_funcs_create rive_hb_unicode_funcs_create
+#define hb_unicode_funcs_destroy rive_hb_unicode_funcs_destroy
+#define hb_unicode_funcs_get_default rive_hb_unicode_funcs_get_default
+#define hb_unicode_funcs_get_empty rive_hb_unicode_funcs_get_empty
 #define hb_unicode_funcs_get_parent rive_hb_unicode_funcs_get_parent
 #define hb_unicode_funcs_get_user_data rive_hb_unicode_funcs_get_user_data
 #define hb_unicode_funcs_is_immutable rive_hb_unicode_funcs_is_immutable
+#define hb_unicode_funcs_lazy_loader_t rive_hb_unicode_funcs_lazy_loader_t
+#define hb_unicode_funcs_make_immutable rive_hb_unicode_funcs_make_immutable
+#define hb_unicode_funcs_reference rive_hb_unicode_funcs_reference
+#define hb_unicode_funcs_set_combining_class_func rive_hb_unicode_funcs_set_combining_class_func
+#define hb_unicode_funcs_set_compose_func rive_hb_unicode_funcs_set_compose_func
 #define hb_unicode_funcs_set_decompose_compatibility_func rive_hb_unicode_funcs_set_decompose_compatibility_func
+#define hb_unicode_funcs_set_decompose_func rive_hb_unicode_funcs_set_decompose_func
 #define hb_unicode_funcs_set_eastasian_width_func rive_hb_unicode_funcs_set_eastasian_width_func
+#define hb_unicode_funcs_set_general_category_func rive_hb_unicode_funcs_set_general_category_func
+#define hb_unicode_funcs_set_mirroring_func rive_hb_unicode_funcs_set_mirroring_func
+#define hb_unicode_funcs_set_script_func rive_hb_unicode_funcs_set_script_func
 #define hb_unicode_funcs_set_user_data rive_hb_unicode_funcs_set_user_data
+#define hb_unicode_funcs_t rive_hb_unicode_funcs_t
 #define hb_unicode_general_category rive_hb_unicode_general_category
+#define hb_unicode_general_category_nil rive_hb_unicode_general_category_nil
+#define hb_unicode_general_category_t rive_hb_unicode_general_category_t
+#define hb_unicode_is_emoji_Extended_Pictographic rive_hb_unicode_is_emoji_Extended_Pictographic
 #define hb_unicode_mirroring rive_hb_unicode_mirroring
+#define hb_unicode_mirroring_nil rive_hb_unicode_mirroring_nil
+#define hb_unicode_props_flags_t rive_hb_unicode_props_flags_t
 #define hb_unicode_script rive_hb_unicode_script
-#define hb_style_get_value rive_hb_style_get_value
-#define hb_style_tag_t rive_hb_style_tag_t
-// __hb_*
-#define _hb_shapers_get rive__hb_shapers_get
-#define _hb_CrapPool rive__hb_CrapPool
-#define _hb_NullPool rive__hb_NullPool
-#define _hb_Null_AAT_Lookup rive__hb_Null_AAT_Lookup
-#define _hb_Null_AAT_SettingName rive__hb_Null_AAT_SettingName
-#define _hb_Null_OT_RangeRecord rive__hb_Null_OT_RangeRecord
-#define _hb_Null_hb_buffer_t rive__hb_Null_hb_buffer_t
-#define _hb_Null_hb_unicode_funcs_t rive__hb_Null_hb_unicode_funcs_t
-#define _hb_options rive__hb_options
-#define _hb_Null_hb_draw_funcs_t rive__hb_Null_hb_draw_funcs_t
-#define _hb_Null_OT_CmapSubtableLongGroup rive__hb_Null_OT_CmapSubtableLongGroup
-#define _hb_Null_hb_face_t rive__hb_Null_hb_face_t
-#define _hb_ot_shaper_face_data_destroy rive__hb_ot_shaper_face_data_destroy
-#define _hb_Null_hb_font_funcs_t rive__hb_Null_hb_font_funcs_t
-#define _hb_Null_hb_font_t rive__hb_Null_hb_font_t
-#define _hb_ot_shaper_font_data_destroy rive__hb_ot_shaper_font_data_destroy
-#define _hb_Null_OT_Index rive__hb_Null_OT_Index
-#define _hb_Null_OT_LangSys rive__hb_Null_OT_LangSys
-#define _hb_modified_combining_class rive__hb_modified_combining_class
-#define _hb_ot_shape rive__hb_ot_shape
-#define _hb_ot_shaper_arabic rive__hb_ot_shaper_arabic
-#define _hb_ot_shaper_default rive__hb_ot_shaper_default
-#define _hb_ot_shaper_dumber rive__hb_ot_shaper_dumber
-#define _hb_ot_shaper_face_data_create rive__hb_ot_shaper_face_data_create
-#define _hb_ot_shaper_font_data_create rive__hb_ot_shaper_font_data_create
-#define _hb_ot_shaper_hangul rive__hb_ot_shaper_hangul
-#define _hb_ot_shaper_hebrew rive__hb_ot_shaper_hebrew
-#define _hb_ot_shaper_indic rive__hb_ot_shaper_indic
-#define _hb_ot_shaper_khmer rive__hb_ot_shaper_khmer
-#define _hb_ot_shaper_myanmar rive__hb_ot_shaper_myanmar
-#define _hb_ot_shaper_myanmar_zawgyi rive__hb_ot_shaper_myanmar_zawgyi
-#define _hb_ot_shaper_thai rive__hb_ot_shaper_thai
-#define _hb_ot_shaper_use rive__hb_ot_shaper_use
-#define _hb_Null_hb_paint_funcs_t rive__hb_Null_hb_paint_funcs_t
-#define _hb_Null_OT_ClipRecord rive__hb_Null_OT_ClipRecord
-#define _hb_Null_OT_VarIdx rive__hb_Null_OT_VarIdx
-#define _hb_subset_accelerator_user_data_key rive__hb_subset_accelerator_user_data_key
-#define lookup_expert_subset_charset_for_sid rive_lookup_expert_subset_charset_for_sid
-#define lookup_standard_encoding_for_sid rive_lookup_standard_encoding_for_sid
-#define data_destroy_arabic rive_data_destroy_arabic
+#define hb_unicode_script_nil rive_hb_unicode_script_nil
+#define hb_unsigned_add_overflows rive_hb_unsigned_add_overflows
+#define hb_unsigned_mul_overflows rive_hb_unsigned_mul_overflows
+#define hb_use_b4 rive_hb_use_b4
+#define hb_use_get_category rive_hb_use_get_category
+#define hb_use_u16 rive_hb_use_u16
+#define hb_use_u8 rive_hb_use_u8
+#define hb_user_data_array_t rive_hb_user_data_array_t
+#define hb_user_data_key_t rive_hb_user_data_key_t
+#define hb_utf16_xe_t rive_hb_utf16_xe_t
+#define hb_utf32_xe_t rive_hb_utf32_xe_t
+#define hb_utf8_t rive_hb_utf8_t
+#define hb_variation_from_string rive_hb_variation_from_string
+#define hb_variation_t rive_hb_variation_t
+#define hb_variation_to_string rive_hb_variation_to_string
+#define hb_vector_size_t rive_hb_vector_size_t
+#define hb_vector_t rive_hb_vector_t
+#define hb_version rive_hb_version
+#define hb_version_atleast rive_hb_version_atleast
+#define hb_version_string rive_hb_version_string
+#define hb_zip rive_hb_zip
+#define hb_zip_iter_t rive_hb_zip_iter_t
+#define lookup_expert_charset_for_glyph rive_lookup_expert_charset_for_glyph
 #define lookup_expert_charset_for_sid rive_lookup_expert_charset_for_sid
-#define lookup_standard_encoding_for_code rive_lookup_standard_encoding_for_code
-#define accelerator_t rive_accelerator_t
 #define lookup_expert_encoding_for_code rive_lookup_expert_encoding_for_code
-#define get_seac_components rive_get_seac_components
+#define lookup_expert_subset_charset_for_glyph rive_lookup_expert_subset_charset_for_glyph
+#define lookup_expert_subset_charset_for_sid rive_lookup_expert_subset_charset_for_sid
+#define lookup_standard_encoding_for_code rive_lookup_standard_encoding_for_code
+#define lookup_standard_encoding_for_sid rive_lookup_standard_encoding_for_sid
+#define minus_1 rive_minus_1
diff --git a/include/rive/text/font_hb.hpp b/include/rive/text/font_hb.hpp
index a63d98b..cf8b31c 100644
--- a/include/rive/text/font_hb.hpp
+++ b/include/rive/text/font_hb.hpp
@@ -5,10 +5,13 @@
 #include "rive/text_engine.hpp"
 
 #include <unordered_map>
+#include <vector>
 
 struct hb_font_t;
 struct hb_draw_funcs_t;
+struct hb_paint_funcs_t;
 struct hb_feature_t;
+using hb_color_t = uint32_t;
 
 class HBFont : public rive::Font
 {
@@ -25,6 +28,12 @@
     bool isItalic() const override;
 
     rive::RawPath getPath(rive::GlyphID) const override;
+    bool hasColorGlyphs() const override;
+    bool isColorGlyph(rive::GlyphID) const override;
+    size_t getColorLayers(
+        rive::GlyphID,
+        std::vector<ColorGlyphLayer>& out,
+        rive::ColorInt foreground = 0xFF000000) const override;
     rive::SimpleArray<rive::Paragraph> onShapeText(
         rive::Span<const rive::Unichar>,
         rive::Span<const rive::TextRun>,
@@ -65,12 +74,22 @@
 
 private:
     hb_draw_funcs_t* m_drawFuncs;
+    hb_paint_funcs_t* m_paintFuncs;
 
     // Feature value lookup based on tag.
     std::unordered_map<uint32_t, uint32_t> m_featureValues;
 
     // Axis value lookup based on for the feature.
     std::unordered_map<uint32_t, float> m_axisValues;
+
+    // Color glyph (emoji) support — COLRv0 (layers), COLRv1 (paint),
+    // and/or SBIX/CBDT (PNG bitmap).
+    bool m_hasColorLayers = false; // COLRv0
+    bool m_hasColorPaint = false;  // COLRv1
+    bool m_hasPNG = false;         // SBIX or CBDT
+    std::vector<hb_color_t> m_paletteColors;
+    mutable std::unordered_map<rive::GlyphID, std::vector<ColorGlyphLayer>>
+        m_colorLayerCache;
 };
 
 #endif
diff --git a/include/rive/text/glyph_lookup.hpp b/include/rive/text/glyph_lookup.hpp
index 9286619..0683b7b 100644
--- a/include/rive/text/glyph_lookup.hpp
+++ b/include/rive/text/glyph_lookup.hpp
@@ -7,7 +7,7 @@
 namespace rive
 {
 
-/// Stores the glyphId/Index representing the unicode point at i.
+/// Stores the glyphId/Index representing the codepoint at i.
 class GlyphLookup
 {
 public:
@@ -18,6 +18,8 @@
 
 public:
     uint32_t count(uint32_t index) const;
+    uint32_t glyphStart(uint32_t index) const;
+    bool isGlyphBoundary(uint32_t index) const;
     size_t size() const { return m_glyphIndices.size(); }
 
     // Returns the glyph index from the computed shape given the codePointIndex
@@ -29,7 +31,7 @@
         return m_glyphIndices[codePointIndex];
     }
 
-    uint32_t lastCodeUnitIndex() const
+    uint32_t lastCodePointIndex() const
     {
         return m_glyphIndices.size() == 0
                    ? 0
diff --git a/include/rive/text/raw_text.hpp b/include/rive/text/raw_text.hpp
index 36b687e..270c773 100644
--- a/include/rive/text/raw_text.hpp
+++ b/include/rive/text/raw_text.hpp
@@ -17,13 +17,15 @@
     /// Returns true if the text object contains no text.
     bool empty() const;
 
-    /// Appends a run to the text object.
+    /// Appends a run to the text object. The foregroundColor is used for
+    /// color glyphs (emoji) that reference the text's foreground color.
     void append(const std::string& text,
                 rcp<RenderPaint> paint,
                 rcp<Font> font,
                 float size = 16.0f,
                 float lineHeight = -1.0f,
-                float letterSpacing = 0.0f);
+                float letterSpacing = 0.0f,
+                ColorInt foregroundColor = 0xFF000000);
 
     /// Resets the text object to empty state (no text).
     void clear();
@@ -68,6 +70,7 @@
         rcp<RenderPaint> paint;
         bool isEmpty;
         ShapePaintPath path;
+        ColorInt foregroundColor = 0xFF000000;
     };
     SimpleArray<Paragraph> m_shape;
     SimpleArray<SimpleArray<GlyphLine>> m_lines;
@@ -90,6 +93,27 @@
     GlyphRun m_ellipsisRun;
     AABB m_bounds;
     rcp<RenderPath> m_clipRenderPath;
+
+    // Color glyph draw commands for interleaving with style paths.
+    struct RawTextDrawCommand
+    {
+        enum Type
+        {
+            kStylePath,
+            kColorGlyph
+        };
+        Type type;
+        RenderStyle* style = nullptr;
+        struct ColorGlyphInfo
+        {
+            rcp<Font> font;
+            GlyphID glyphId;
+            Mat2D transform;
+            ColorInt foregroundColor;
+        };
+        ColorGlyphInfo colorGlyph;
+    };
+    std::vector<RawTextDrawCommand> m_drawCommands;
 };
 } // namespace rive
 
diff --git a/include/rive/text/raw_text_input.hpp b/include/rive/text/raw_text_input.hpp
index cf177eb..e0021c5 100644
--- a/include/rive/text/raw_text_input.hpp
+++ b/include/rive/text/raw_text_input.hpp
@@ -157,6 +157,7 @@
 
     const OrderedLine* orderedLine(CursorPosition position) const;
 
+    void ensureShape();
     void buildTextPaths(Factory* factory);
     void computeVisualPositionFromCursor();
     void setTextPrivate(std::string value);
diff --git a/include/rive/text/text.hpp b/include/rive/text/text.hpp
index 773854c..801a1d5 100644
--- a/include/rive/text/text.hpp
+++ b/include/rive/text/text.hpp
@@ -15,13 +15,39 @@
 #include "rive/viewmodel/property_symbol_dependent.hpp"
 #include "rive/dirtyable.hpp"
 
+#include <functional>
 #include <unordered_map>
 #include <vector>
 
 namespace rive
 {
 
+class Factory;
+class Renderer;
 class TextModifierGroup;
+class TextStylePaint;
+
+// A draw command for interleaving monochrome style paths and color glyphs.
+struct TextDrawCommand
+{
+    enum Type
+    {
+        kStylePath,
+        kColorGlyph
+    };
+    Type type;
+    TextStylePaint* style = nullptr; // for kStylePath
+
+    struct ColorGlyphInfo
+    {
+        rcp<Font> font;
+        GlyphID glyphId;
+        Mat2D transform;
+        ColorInt foregroundColor;
+        float opacity;
+    };
+    ColorGlyphInfo colorGlyph; // for kColorGlyph
+};
 
 class StyledText
 {
@@ -110,7 +136,27 @@
 };
 #endif
 
-class TextStylePaint;
+struct ColorGlyphCacheKey
+{
+    const Font* font;
+    GlyphID glyphId;
+    bool operator==(const ColorGlyphCacheKey& o) const
+    {
+        return font == o.font && glyphId == o.glyphId;
+    }
+};
+
+struct ColorGlyphCacheHash
+{
+    size_t operator()(const ColorGlyphCacheKey& k) const
+    {
+        size_t h = std::hash<const void*>()(k.font);
+        h ^=
+            std::hash<uint16_t>()(k.glyphId) + 0x9e3779b9 + (h << 6) + (h >> 2);
+        return h;
+    }
+};
+
 class Text : public TextBase,
              public TextInterface,
              public DataBindListItemConsumer
@@ -225,6 +271,7 @@
     std::vector<TextValueRun*> m_runs;
     std::vector<TextValueRun*> m_allRuns;
     std::vector<TextStylePaint*> m_renderStyles;
+    std::vector<TextDrawCommand> m_drawCommands;
     SimpleArray<Paragraph> m_shape;
     SimpleArray<Paragraph> m_modifierShape;
     SimpleArray<SimpleArray<GlyphLine>> m_lines;
@@ -243,6 +290,12 @@
     std::vector<TextStylePaint*> m_textStylePaints;
 
     void clearRenderStyles();
+    void drawColorGlyph(Renderer* renderer,
+                        const TextDrawCommand::ColorGlyphInfo& info,
+                        const Mat2D& worldTransform);
+    std::
+        unordered_map<ColorGlyphCacheKey, rcp<RenderImage>, ColorGlyphCacheHash>
+            m_emojiImageCache;
     TextBoundsInfo computeBoundsInfo();
     LineIter shouldDrawLine(float y, float totalHeight, const GlyphLine& line);
     void buildTextStylePaints();
diff --git a/include/rive/text/text_style_paint.hpp b/include/rive/text/text_style_paint.hpp
index 2ec96e1..9b33053 100644
--- a/include/rive/text/text_style_paint.hpp
+++ b/include/rive/text/text_style_paint.hpp
@@ -15,6 +15,10 @@
     void rewindPath();
     void draw(Renderer* renderer, const Mat2D& worldTransform);
 
+    /// Returns the foreground color from the first solid fill, or black if
+    /// none.
+    ColorInt foregroundColor() const;
+
     // Implemented for ShapePaintContainer.
     const Mat2D& shapeWorldTransform() const override;
     Component* pathBuilder() override;
@@ -31,4 +35,4 @@
 };
 } // namespace rive
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/rive/text_engine.hpp b/include/rive/text_engine.hpp
index 02b0b2b..14e21eb 100644
--- a/include/rive/text_engine.hpp
+++ b/include/rive/text_engine.hpp
@@ -7,9 +7,12 @@
 
 #include "rive/math/raw_path.hpp"
 #include "rive/refcnt.hpp"
+#include "rive/shapes/paint/color.hpp"
 #include "rive/span.hpp"
 #include "rive/simple_array.hpp"
 
+#include <vector>
+
 namespace rive
 {
 
@@ -224,6 +227,67 @@
     //
     virtual RawPath getPath(GlyphID) const = 0;
 
+    // Color glyph (emoji) support via COLR/CPAL tables.
+
+    // A single layer of a color glyph, with its own path and fill.
+    struct GradientStop
+    {
+        float offset;
+        ColorInt color;
+    };
+
+    enum class ColorGlyphPaintType : uint8_t
+    {
+        solid,
+        linearGradient,
+        radialGradient,
+        sweepGradient,
+        image,
+    };
+
+    struct ColorGlyphLayer
+    {
+        RawPath path;
+        ColorGlyphPaintType paintType = ColorGlyphPaintType::solid;
+        ColorInt color = 0xFF000000; // ARGB (for solid fills)
+        bool useForeground = false;  // true if color should use text color
+
+        // Gradient data (only valid when paintType != solid).
+        std::vector<GradientStop> stops;
+        // Linear gradient: (x0,y0) start, (x1,y1) end.
+        // Radial gradient: (x0,y0,r0) inner circle, (x1,y1,r1) outer circle.
+        // Sweep gradient: (x0,y0) center, startAngle, endAngle.
+        float x0 = 0, y0 = 0, x1 = 0, y1 = 0;
+        float r0 = 0, r1 = 0;               // radial
+        float startAngle = 0, endAngle = 0; // sweep
+
+        // Image data (only valid when paintType == image).
+        // Raw encoded image bytes (e.g. PNG from SBIX/CBDT).
+        std::vector<uint8_t> imageBytes;
+        unsigned int imageWidth = 0, imageHeight = 0;
+        // Glyph extents for positioning the image.
+        float imageBearingX = 0, imageBearingY = 0;
+        float imageExtentX = 0, imageExtentY = 0;
+    };
+
+    // Whether this font contains any COLR color glyphs.
+    virtual bool hasColorGlyphs() const { return false; }
+
+    // Whether a specific glyph has color layers.
+    virtual bool isColorGlyph(GlyphID) const { return false; }
+
+    // Decompose a color glyph into its colored layers. Returns the number
+    // of layers written to `out`. If the glyph is not a color glyph,
+    // returns 0.
+    virtual size_t getColorLayers(GlyphID,
+                                  std::vector<ColorGlyphLayer>& out,
+                                  ColorInt foreground = 0xFF000000) const
+    {
+        (void)out;
+        (void)foreground;
+        return 0;
+    }
+
     SimpleArray<Paragraph> shapeText(Span<const Unichar> text,
                                      Span<const TextRun> runs,
                                      int textDirectionFlag = -1) const;
diff --git a/src/text/cursor.cpp b/src/text/cursor.cpp
index 3ebe4f7..529c285 100644
--- a/src/text/cursor.cpp
+++ b/src/text/cursor.cpp
@@ -207,21 +207,21 @@
         std::min(m_lineIndex,
                  subtractUint32((uint32_t)shape.orderedLines().size(), 1)),
         std::min(m_codePointIndex,
-                 subtractUint32(shape.glyphLookup().lastCodeUnitIndex(), 1)));
+                 subtractUint32(shape.glyphLookup().lastCodePointIndex(), 1)));
 }
 
 CursorPosition CursorPosition::atIndex(uint32_t codePointIndex,
                                        const FullyShapedText& shape)
 {
-    // Don't go to actual last code unit index as we always insert a zero width
+    // Don't go to actual last codepoint index as we always insert a zero width
     // space.
     // https://en.wikipedia.org/wiki/Zero-width_space
     if (codePointIndex >=
-        subtractUint32(shape.glyphLookup().lastCodeUnitIndex(), 1))
+        subtractUint32(shape.glyphLookup().lastCodePointIndex(), 1))
     {
         return CursorPosition(
             subtractUint32((uint32_t)shape.orderedLines().size(), 1),
-            subtractUint32(shape.glyphLookup().lastCodeUnitIndex(), 1));
+            subtractUint32(shape.glyphLookup().lastCodePointIndex(), 1));
     }
 
     const SimpleArray<Paragraph>& paragraphs = shape.paragraphs();
diff --git a/src/text/font_hb.cpp b/src/text/font_hb.cpp
index 8271802..8bc6eca 100644
--- a/src/text/font_hb.cpp
+++ b/src/text/font_hb.cpp
@@ -9,6 +9,7 @@
 
 #include "rive/factory.hpp"
 #include "rive/renderer_utils.hpp"
+#include "rive/shapes/paint/color.hpp"
 
 #include "hb.h"
 #include "hb-ot.h"
@@ -130,6 +131,342 @@
     }
 }
 
+// Convert HarfBuzz color (BGRA byte order) to Rive ColorInt (ARGB).
+static rive::ColorInt hbColorToColorInt(hb_color_t c)
+{
+    uint8_t b = hb_color_get_blue(c);
+    uint8_t g = hb_color_get_green(c);
+    uint8_t r = hb_color_get_red(c);
+    uint8_t a = hb_color_get_alpha(c);
+    return rive::colorARGB(a, r, g, b);
+}
+
+// ── COLRv1 paint callbacks ──────────────────────────────────────────────
+// We flatten the COLRv1 paint tree into a list of (path, fill) layers.
+
+struct PaintState
+{
+    hb_font_t* font;
+    hb_draw_funcs_t* drawFuncs;
+    std::vector<rive::Font::ColorGlyphLayer>* layers;
+    rive::GlyphID clipGlyph = 0;
+    bool hasClip = false;
+    rive::ColorInt foreground = 0xFF000000;
+
+    // Transform stack for gradient coordinates.
+    // HarfBuzz gives gradient coords in the local space of the paint;
+    // transforms map them to glyph space.
+    std::vector<rive::Mat2D> transformStack;
+
+    void pushTransform(float xx,
+                       float yx,
+                       float xy,
+                       float yy,
+                       float dx,
+                       float dy)
+    {
+        rive::Mat2D m;
+        m[0] = xx;
+        m[1] = yx;
+        m[2] = xy;
+        m[3] = yy;
+        m[4] = dx * gInvScale;
+        m[5] = -dy * gInvScale;
+        if (transformStack.empty())
+        {
+            transformStack.push_back(m);
+        }
+        else
+        {
+            transformStack.push_back(transformStack.back() * m);
+        }
+    }
+
+    void popTransform()
+    {
+        if (!transformStack.empty())
+        {
+            transformStack.pop_back();
+        }
+    }
+
+    rive::Vec2D mapPoint(float x, float y) const
+    {
+        // Scale from HB font units to Rive glyph units, and flip Y.
+        float rx = x * gInvScale;
+        float ry = -y * gInvScale;
+        if (!transformStack.empty())
+        {
+            // The transform stack already incorporates gInvScale + Y flip
+            // in pushTransform, so just apply raw coords.
+            const auto& m = transformStack.back();
+            return rive::Vec2D(m[0] * x + m[2] * y + m[4],
+                               m[1] * x + m[3] * y + m[5]);
+        }
+        return rive::Vec2D(rx, ry);
+    }
+
+    float mapRadius(float r) const
+    {
+        float scaled = r * gInvScale;
+        if (!transformStack.empty())
+        {
+            // Use the geometric mean of the scale factors.
+            const auto& m = transformStack.back();
+            float sx = std::sqrt(m[0] * m[0] + m[1] * m[1]);
+            return r * sx; // Don't double-apply gInvScale; it's in the matrix.
+        }
+        return scaled;
+    }
+
+    // Helper: extract color stops from hb_color_line_t.
+    static std::vector<rive::Font::GradientStop> extractStops(
+        hb_color_line_t* colorLine,
+        rive::ColorInt foreground)
+    {
+        unsigned int count = 0;
+        hb_color_line_get_color_stops(colorLine, 0, &count, nullptr);
+        std::vector<hb_color_stop_t> hbStops(count);
+        hb_color_line_get_color_stops(colorLine, 0, &count, hbStops.data());
+        std::vector<rive::Font::GradientStop> stops;
+        stops.reserve(count);
+        for (auto& s : hbStops)
+        {
+            rive::ColorInt c =
+                s.is_foreground ? foreground : hbColorToColorInt(s.color);
+            stops.push_back({s.offset, c});
+        }
+        return stops;
+    }
+
+    // Helper: emit a layer with the current clip glyph path.
+    rive::Font::ColorGlyphLayer makeClipLayer() const
+    {
+        rive::Font::ColorGlyphLayer layer;
+        hb_font_draw_glyph(font, clipGlyph, drawFuncs, &layer.path);
+        return layer;
+    }
+};
+
+static void paint_push_transform(hb_paint_funcs_t*,
+                                 void* paint_data,
+                                 float xx,
+                                 float yx,
+                                 float xy,
+                                 float yy,
+                                 float dx,
+                                 float dy,
+                                 void*)
+{
+    ((PaintState*)paint_data)->pushTransform(xx, yx, xy, yy, dx, dy);
+}
+
+static void paint_pop_transform(hb_paint_funcs_t*, void* paint_data, void*)
+{
+    ((PaintState*)paint_data)->popTransform();
+}
+
+static void paint_push_clip_glyph(hb_paint_funcs_t*,
+                                  void* paint_data,
+                                  hb_codepoint_t glyph,
+                                  hb_font_t*,
+                                  void*)
+{
+    auto* state = (PaintState*)paint_data;
+    state->clipGlyph = (rive::GlyphID)glyph;
+    state->hasClip = true;
+}
+
+static void paint_push_clip_rectangle(hb_paint_funcs_t*,
+                                      void*,
+                                      float,
+                                      float,
+                                      float,
+                                      float,
+                                      void*)
+{}
+
+static void paint_pop_clip(hb_paint_funcs_t*, void* paint_data, void*)
+{
+    ((PaintState*)paint_data)->hasClip = false;
+}
+
+static void paint_solid(hb_paint_funcs_t*,
+                        void* paint_data,
+                        hb_bool_t is_foreground,
+                        hb_color_t color,
+                        void*)
+{
+    auto* state = (PaintState*)paint_data;
+    if (!state->hasClip)
+        return;
+
+    auto layer = state->makeClipLayer();
+    layer.paintType = rive::Font::ColorGlyphPaintType::solid;
+    if (is_foreground)
+    {
+        layer.useForeground = true;
+        layer.color = state->foreground;
+    }
+    else
+    {
+        layer.color = hbColorToColorInt(color);
+    }
+    state->layers->push_back(std::move(layer));
+}
+
+static void paint_linear_gradient(hb_paint_funcs_t*,
+                                  void* paint_data,
+                                  hb_color_line_t* colorLine,
+                                  float x0,
+                                  float y0,
+                                  float x1,
+                                  float y1,
+                                  float x2,
+                                  float y2,
+                                  void*)
+{
+    auto* state = (PaintState*)paint_data;
+    if (!state->hasClip)
+        return;
+
+    auto layer = state->makeClipLayer();
+    layer.paintType = rive::Font::ColorGlyphPaintType::linearGradient;
+    layer.stops = PaintState::extractStops(colorLine, state->foreground);
+
+    // OpenType linear gradient uses 3 points: p0 (start), p1 (end), p2
+    // (rotation). The gradient line goes from p0 toward p1, and p2 is used
+    // to rotate the direction. For Rive we need a 2-point definition.
+    // The actual gradient direction is: start = p0, end = p1 projected
+    // along the p0->p2 direction. For simplicity, just use p0 and p1.
+    auto sp0 = state->mapPoint(x0, y0);
+    auto sp1 = state->mapPoint(x1, y1);
+    layer.x0 = sp0.x;
+    layer.y0 = sp0.y;
+    layer.x1 = sp1.x;
+    layer.y1 = sp1.y;
+
+    state->layers->push_back(std::move(layer));
+}
+
+static void paint_radial_gradient(hb_paint_funcs_t*,
+                                  void* paint_data,
+                                  hb_color_line_t* colorLine,
+                                  float x0,
+                                  float y0,
+                                  float radius0,
+                                  float x1,
+                                  float y1,
+                                  float radius1,
+                                  void*)
+{
+    auto* state = (PaintState*)paint_data;
+    if (!state->hasClip)
+        return;
+
+    auto layer = state->makeClipLayer();
+    layer.paintType = rive::Font::ColorGlyphPaintType::radialGradient;
+    layer.stops = PaintState::extractStops(colorLine, state->foreground);
+
+    auto sp0 = state->mapPoint(x0, y0);
+    auto sp1 = state->mapPoint(x1, y1);
+    layer.x0 = sp0.x;
+    layer.y0 = sp0.y;
+    layer.x1 = sp1.x;
+    layer.y1 = sp1.y;
+    layer.r0 = state->mapRadius(radius0);
+    layer.r1 = state->mapRadius(radius1);
+
+    state->layers->push_back(std::move(layer));
+}
+
+static void paint_sweep_gradient(hb_paint_funcs_t*,
+                                 void* paint_data,
+                                 hb_color_line_t* colorLine,
+                                 float cx,
+                                 float cy,
+                                 float startAngle,
+                                 float endAngle,
+                                 void*)
+{
+    auto* state = (PaintState*)paint_data;
+    if (!state->hasClip)
+        return;
+
+    auto layer = state->makeClipLayer();
+    layer.paintType = rive::Font::ColorGlyphPaintType::sweepGradient;
+    layer.stops = PaintState::extractStops(colorLine, state->foreground);
+
+    auto sc = state->mapPoint(cx, cy);
+    layer.x0 = sc.x;
+    layer.y0 = sc.y;
+    layer.startAngle = startAngle;
+    layer.endAngle = endAngle;
+
+    state->layers->push_back(std::move(layer));
+}
+
+static void paint_push_group(hb_paint_funcs_t*, void*, void*) {}
+static void paint_pop_group(hb_paint_funcs_t*,
+                            void*,
+                            hb_paint_composite_mode_t,
+                            void*)
+{}
+
+static hb_bool_t paint_color_glyph(hb_paint_funcs_t*,
+                                   void*,
+                                   hb_codepoint_t,
+                                   hb_font_t*,
+                                   void*)
+{
+    return false;
+}
+
+static hb_bool_t paint_image(hb_paint_funcs_t*,
+                             void* paint_data,
+                             hb_blob_t* blob,
+                             unsigned int width,
+                             unsigned int height,
+                             hb_tag_t format,
+                             float slant,
+                             hb_glyph_extents_t* extents,
+                             void*)
+{
+    // We only support PNG images (SBIX / CBDT).
+    if (format != HB_TAG('p', 'n', 'g', ' '))
+    {
+        return false;
+    }
+
+    unsigned int length;
+    const char* data = hb_blob_get_data(blob, &length);
+    if (data == nullptr || length == 0)
+    {
+        return false;
+    }
+
+    auto* state = (PaintState*)paint_data;
+
+    rive::Font::ColorGlyphLayer layer;
+    layer.paintType = rive::Font::ColorGlyphPaintType::image;
+    layer.imageBytes.assign(reinterpret_cast<const uint8_t*>(data),
+                            reinterpret_cast<const uint8_t*>(data) + length);
+    layer.imageWidth = width;
+    layer.imageHeight = height;
+    if (extents != nullptr)
+    {
+        layer.imageBearingX = extents->x_bearing * gInvScale;
+        layer.imageBearingY = -extents->y_bearing * gInvScale;
+        layer.imageExtentX = extents->width * gInvScale;
+        layer.imageExtentY = -extents->height * gInvScale;
+    }
+
+    state->layers->push_back(std::move(layer));
+    return true;
+}
+
+// ────────────────────────────────────────────────────────────────────────
+
 static rive::Font::LineMetrics make_lmx(hb_font_t* font)
 {
     // premable on font...
@@ -175,11 +512,82 @@
                                       nullptr,
                                       nullptr);
     hb_draw_funcs_make_immutable(m_drawFuncs);
+
+    // Initialize COLRv1 paint funcs.
+    m_paintFuncs = hb_paint_funcs_create();
+    hb_paint_funcs_set_push_transform_func(m_paintFuncs,
+                                           paint_push_transform,
+                                           nullptr,
+                                           nullptr);
+    hb_paint_funcs_set_pop_transform_func(m_paintFuncs,
+                                          paint_pop_transform,
+                                          nullptr,
+                                          nullptr);
+    hb_paint_funcs_set_push_clip_glyph_func(m_paintFuncs,
+                                            paint_push_clip_glyph,
+                                            nullptr,
+                                            nullptr);
+    hb_paint_funcs_set_push_clip_rectangle_func(m_paintFuncs,
+                                                paint_push_clip_rectangle,
+                                                nullptr,
+                                                nullptr);
+    hb_paint_funcs_set_pop_clip_func(m_paintFuncs,
+                                     paint_pop_clip,
+                                     nullptr,
+                                     nullptr);
+    hb_paint_funcs_set_color_func(m_paintFuncs, paint_solid, nullptr, nullptr);
+    hb_paint_funcs_set_push_group_func(m_paintFuncs,
+                                       paint_push_group,
+                                       nullptr,
+                                       nullptr);
+    hb_paint_funcs_set_pop_group_func(m_paintFuncs,
+                                      paint_pop_group,
+                                      nullptr,
+                                      nullptr);
+    hb_paint_funcs_set_color_glyph_func(m_paintFuncs,
+                                        paint_color_glyph,
+                                        nullptr,
+                                        nullptr);
+    hb_paint_funcs_set_linear_gradient_func(m_paintFuncs,
+                                            paint_linear_gradient,
+                                            nullptr,
+                                            nullptr);
+    hb_paint_funcs_set_radial_gradient_func(m_paintFuncs,
+                                            paint_radial_gradient,
+                                            nullptr,
+                                            nullptr);
+    hb_paint_funcs_set_sweep_gradient_func(m_paintFuncs,
+                                           paint_sweep_gradient,
+                                           nullptr,
+                                           nullptr);
+    hb_paint_funcs_set_image_func(m_paintFuncs, paint_image, nullptr, nullptr);
+    hb_paint_funcs_make_immutable(m_paintFuncs);
+
+    // Initialize color glyph (COLR/CPAL/SBIX/CBDT) support.
+    hb_face_t* face = hb_font_get_face(font);
+    m_hasColorLayers = hb_ot_color_has_layers(face);
+    m_hasColorPaint = hb_ot_color_has_paint(face);
+    m_hasPNG = hb_ot_color_has_png(face);
+    if (m_hasColorLayers || m_hasColorPaint)
+    {
+        unsigned int colorCount = 0;
+        hb_ot_color_palette_get_colors(face, 0, 0, &colorCount, nullptr);
+        if (colorCount > 0)
+        {
+            m_paletteColors.resize(colorCount);
+            hb_ot_color_palette_get_colors(face,
+                                           0,
+                                           0,
+                                           &colorCount,
+                                           m_paletteColors.data());
+        }
+    }
 }
 
 HBFont::~HBFont()
 {
     hb_draw_funcs_destroy(m_drawFuncs);
+    hb_paint_funcs_destroy(m_paintFuncs);
     hb_font_destroy(m_font);
 }
 
@@ -384,6 +792,178 @@
     return rpath;
 }
 
+bool HBFont::hasColorGlyphs() const
+{
+    return m_hasColorLayers || m_hasColorPaint || m_hasPNG;
+}
+
+bool HBFont::isColorGlyph(rive::GlyphID glyph) const
+{
+    if (!m_hasColorLayers && !m_hasColorPaint && !m_hasPNG)
+    {
+        return false;
+    }
+    hb_face_t* face = hb_font_get_face(m_font);
+    // Check COLRv0 layers first.
+    if (m_hasColorLayers)
+    {
+        unsigned int total =
+            hb_ot_color_glyph_get_layers(face, glyph, 0, nullptr, nullptr);
+        if (total > 0)
+        {
+            return true;
+        }
+    }
+    // Check COLRv1 paint.
+    if (m_hasColorPaint)
+    {
+        if (hb_ot_color_glyph_has_paint(face, glyph))
+        {
+            return true;
+        }
+    }
+    // Check SBIX/CBDT PNG.
+    if (m_hasPNG)
+    {
+        hb_blob_t* blob = hb_ot_color_glyph_reference_png(m_font, glyph);
+        if (blob != nullptr)
+        {
+            bool has = hb_blob_get_length(blob) > 0;
+            hb_blob_destroy(blob);
+            return has;
+        }
+    }
+    return false;
+}
+
+size_t HBFont::getColorLayers(rive::GlyphID glyph,
+                              std::vector<ColorGlyphLayer>& out,
+                              rive::ColorInt foreground) const
+{
+    if (!m_hasColorLayers && !m_hasColorPaint && !m_hasPNG)
+    {
+        return 0;
+    }
+
+    // Check cache first.
+    auto cacheIt = m_colorLayerCache.find(glyph);
+    if (cacheIt != m_colorLayerCache.end())
+    {
+        // Copy from cache, but update foreground colors.
+        for (const auto& cached : cacheIt->second)
+        {
+            ColorGlyphLayer layer;
+            layer.paintType = cached.paintType;
+            layer.path = cached.path;
+            layer.useForeground = cached.useForeground;
+            layer.color = cached.useForeground ? foreground : cached.color;
+            // Copy gradient data if present.
+            layer.stops = cached.stops;
+            layer.x0 = cached.x0;
+            layer.y0 = cached.y0;
+            layer.x1 = cached.x1;
+            layer.y1 = cached.y1;
+            layer.r0 = cached.r0;
+            layer.r1 = cached.r1;
+            layer.startAngle = cached.startAngle;
+            layer.endAngle = cached.endAngle;
+            // Copy image data if present.
+            layer.imageBytes = cached.imageBytes;
+            layer.imageWidth = cached.imageWidth;
+            layer.imageHeight = cached.imageHeight;
+            layer.imageBearingX = cached.imageBearingX;
+            layer.imageBearingY = cached.imageBearingY;
+            layer.imageExtentX = cached.imageExtentX;
+            layer.imageExtentY = cached.imageExtentY;
+            out.push_back(std::move(layer));
+        }
+        return cacheIt->second.size();
+    }
+
+    std::vector<ColorGlyphLayer> layers;
+    hb_face_t* face = hb_font_get_face(m_font);
+
+    // Try COLRv0 first.
+    if (m_hasColorLayers)
+    {
+        unsigned int layerCount =
+            hb_ot_color_glyph_get_layers(face, glyph, 0, nullptr, nullptr);
+        if (layerCount > 0)
+        {
+            std::vector<hb_ot_color_layer_t> hbLayers(layerCount);
+            hb_ot_color_glyph_get_layers(face,
+                                         glyph,
+                                         0,
+                                         &layerCount,
+                                         hbLayers.data());
+
+            layers.reserve(layerCount);
+            for (unsigned int i = 0; i < layerCount; i++)
+            {
+                ColorGlyphLayer layer;
+                hb_font_draw_glyph(m_font,
+                                   hbLayers[i].glyph,
+                                   m_drawFuncs,
+                                   &layer.path);
+                if (hbLayers[i].color_index == 0xFFFF)
+                {
+                    layer.useForeground = true;
+                    layer.color = foreground;
+                }
+                else
+                {
+                    layer.useForeground = false;
+                    if (hbLayers[i].color_index < m_paletteColors.size())
+                    {
+                        layer.color = hbColorToColorInt(
+                            m_paletteColors[hbLayers[i].color_index]);
+                    }
+                    else
+                    {
+                        layer.color = 0xFF000000;
+                    }
+                }
+                layers.push_back(std::move(layer));
+            }
+        }
+    }
+
+    // Fall back to COLRv1 paint if no COLRv0 layers found.
+    if (layers.empty() && (m_hasColorPaint || m_hasPNG))
+    {
+        // hb_font_paint_glyph handles both COLRv1 and SBIX/CBDT.
+        // For COLRv1 it calls paint_solid/gradient callbacks;
+        // for SBIX/CBDT it calls paint_image.
+        PaintState state;
+        state.font = m_font;
+        state.drawFuncs = m_drawFuncs;
+        state.layers = &layers;
+        state.foreground = foreground;
+
+        hb_font_paint_glyph(m_font,
+                            glyph,
+                            m_paintFuncs,
+                            &state,
+                            0,                       // palette_index
+                            HB_COLOR(0, 0, 0, 255)); // foreground
+    }
+
+    if (layers.empty())
+    {
+        return 0;
+    }
+
+    size_t count = layers.size();
+    // Cache the result.
+    m_colorLayerCache[glyph] = layers;
+    // Move into output.
+    for (auto& layer : layers)
+    {
+        out.push_back(std::move(layer));
+    }
+    return count;
+}
+
 ///////////////////////////////////////////////////////////
 
 static rive::GlyphRun shape_run(const rive::Unichar text[],
diff --git a/src/text/glyph_lookup.cpp b/src/text/glyph_lookup.cpp
index a30f20d..acb4669 100644
--- a/src/text/glyph_lookup.cpp
+++ b/src/text/glyph_lookup.cpp
@@ -6,9 +6,9 @@
 void GlyphLookup::compute(Span<const Unichar> text,
                           const SimpleArray<Paragraph>& shape)
 {
-    size_t codeUnitCount = text.size();
-    m_glyphIndices.resize(codeUnitCount + 1);
-    // Build a mapping of codePoints to glyphs indices.
+    size_t codePointCount = text.size();
+    m_glyphIndices.resize(codePointCount + 1);
+    // Build a mapping of codepoints to glyph indices.
     uint32_t glyphIndex = 0;
     uint32_t lastTextIndex = 0;
     for (const Paragraph& paragraph : shape)
@@ -28,15 +28,15 @@
             }
         }
     }
-    for (size_t i = lastTextIndex; i < codeUnitCount; i++)
+    for (size_t i = lastTextIndex; i < codePointCount; i++)
     {
         m_glyphIndices[i] = glyphIndex - 1;
     }
 
     // Store a fake unreachable glyph at the end to allow selecting the last
     // one.
-    m_glyphIndices[codeUnitCount] =
-        codeUnitCount == 0 ? 0 : m_glyphIndices[codeUnitCount - 1] + 1;
+    m_glyphIndices[codePointCount] =
+        codePointCount == 0 ? 0 : m_glyphIndices[codePointCount - 1] + 1;
 }
 
 uint32_t GlyphLookup::count(uint32_t index) const
@@ -53,6 +53,29 @@
     return count;
 }
 
+uint32_t GlyphLookup::glyphStart(uint32_t index) const
+{
+    if (index == 0 || index >= (uint32_t)m_glyphIndices.size())
+    {
+        return index;
+    }
+    uint32_t value = m_glyphIndices[index];
+    while (index > 0 && m_glyphIndices[index - 1] == value)
+    {
+        index--;
+    }
+    return index;
+}
+
+bool GlyphLookup::isGlyphBoundary(uint32_t index) const
+{
+    if (index == 0 || index >= (uint32_t)m_glyphIndices.size())
+    {
+        return true;
+    }
+    return m_glyphIndices[index] != m_glyphIndices[index - 1];
+}
+
 float GlyphLookup::advanceFactor(int32_t codePointIndex, bool inv) const
 {
     if (codePointIndex < 0 || codePointIndex >= (int32_t)m_glyphIndices.size())
diff --git a/src/text/raw_text.cpp b/src/text/raw_text.cpp
index bcb953d..423be2b 100644
--- a/src/text/raw_text.cpp
+++ b/src/text/raw_text.cpp
@@ -2,6 +2,7 @@
 #include "rive/text/raw_text.hpp"
 #include "rive/text_engine.hpp"
 #include "rive/factory.hpp"
+#include "rive/shapes/paint/color.hpp"
 
 using namespace rive;
 
@@ -13,7 +14,8 @@
                      rcp<Font> font,
                      float size,
                      float lineHeight,
-                     float letterSpacing)
+                     float letterSpacing,
+                     ColorInt foregroundColor)
 {
     int styleIndex = 0;
     for (RenderStyle& style : m_styles)
@@ -24,9 +26,13 @@
         }
         styleIndex++;
     }
-    if (styleIndex == m_styles.size())
+    if (styleIndex == (int)m_styles.size())
     {
-        m_styles.push_back({paint, true});
+        m_styles.emplace_back();
+        auto& style = m_styles.back();
+        style.paint = paint;
+        style.isEmpty = true;
+        style.foregroundColor = foregroundColor;
     }
     m_styled.append(font, size, lineHeight, letterSpacing, text, styleIndex);
     m_dirty = true;
@@ -112,6 +118,7 @@
         style.isEmpty = true;
     }
     m_renderStyles.clear();
+    m_drawCommands.clear();
     if (m_styled.empty())
     {
         return;
@@ -291,8 +298,6 @@
                 GlyphID glyphId = run->glyphs[glyphIndex];
                 float advance = run->advances[glyphIndex];
 
-                RawPath path = font->getPath(glyphId);
-
                 assert(run->styleId < m_styles.size());
                 RenderStyle* style = &m_styles[run->styleId];
                 assert(style != nullptr);
@@ -305,15 +310,32 @@
                                 renderY + offset.y);
 
                 x += advance;
-                style->path.addPathClockwise(path, &transform);
 
-                if (style->isEmpty)
+                if (font->isColorGlyph(glyphId))
                 {
-                    // This was the first path added to the style, so let's mark
-                    // it in our draw list.
-                    style->isEmpty = false;
+                    RawTextDrawCommand cmd;
+                    cmd.type = RawTextDrawCommand::kColorGlyph;
+                    cmd.colorGlyph = {run->font,
+                                      glyphId,
+                                      transform,
+                                      style->foregroundColor};
+                    m_drawCommands.push_back(std::move(cmd));
+                }
+                else
+                {
+                    RawPath path = font->getPath(glyphId);
+                    style->path.addPathClockwise(path, &transform);
 
-                    m_renderStyles.push_back(style);
+                    if (style->isEmpty)
+                    {
+                        style->isEmpty = false;
+                        m_renderStyles.push_back(style);
+
+                        RawTextDrawCommand cmd;
+                        cmd.type = RawTextDrawCommand::kStylePath;
+                        cmd.style = style;
+                        m_drawCommands.push_back(std::move(cmd));
+                    }
                 }
             }
             if (lineIndex == ellipsisLine)
@@ -353,12 +375,41 @@
         renderer->save();
         renderer->clipPath(m_clipRenderPath.get());
     }
-    for (auto style : m_renderStyles)
+    for (auto& cmd : m_drawCommands)
     {
-        auto renderPaint = paint ? paint.get() : style->paint.get();
-        if (renderPaint != nullptr)
+        if (cmd.type == RawTextDrawCommand::kStylePath)
         {
-            renderer->drawPath(style->path.renderPath(m_factory), renderPaint);
+            auto renderPaint = paint ? paint.get() : cmd.style->paint.get();
+            if (renderPaint != nullptr)
+            {
+                renderer->drawPath(cmd.style->path.renderPath(m_factory),
+                                   renderPaint);
+            }
+        }
+        else
+        {
+            // Draw color glyph layers.
+            std::vector<Font::ColorGlyphLayer> layers;
+            auto& info = cmd.colorGlyph;
+            size_t count = info.font->getColorLayers(info.glyphId,
+                                                     layers,
+                                                     info.foregroundColor);
+            if (count > 0)
+            {
+                renderer->save();
+                renderer->transform(info.transform);
+                for (auto& layer : layers)
+                {
+                    auto renderPath =
+                        m_factory->makeRenderPath(layer.path,
+                                                  FillRule::nonZero);
+                    auto layerPaint = m_factory->makeRenderPaint();
+                    layerPaint->style(RenderPaintStyle::fill);
+                    layerPaint->color(layer.color);
+                    renderer->drawPath(renderPath.get(), layerPaint.get());
+                }
+                renderer->restore();
+            }
         }
     }
     if (m_overflow == TextOverflow::clipped && m_clipRenderPath)
diff --git a/src/text/raw_text_input.cpp b/src/text/raw_text_input.cpp
index be6bb22..54f625e 100644
--- a/src/text/raw_text_input.cpp
+++ b/src/text/raw_text_input.cpp
@@ -50,7 +50,6 @@
 void RawTextInput::backspace(int32_t direction)
 {
     Cursor startingCursor = m_cursor;
-    int32_t offset = direction > 0 ? 0 : -1;
     if (!m_cursor.isCollapsed())
     {
         erase();
@@ -59,15 +58,37 @@
     }
     m_idealCursorX = -1.0f;
 
-    auto index = m_cursor.first().codePointIndex(offset);
-
-    if (index >= m_text.size() - 1)
+    ensureShape();
+    const auto& glyphLookup = m_shape.glyphLookup();
+    if (direction > 0)
     {
-        return;
+        // Delete forward: erase the full glyph cluster at cursor position.
+        auto index = m_cursor.first().codePointIndex();
+        if (index >= m_text.size() - 1)
+        {
+            return;
+        }
+        uint32_t clusterCount = glyphLookup.count(index);
+        m_text.erase(m_text.begin() + index,
+                     m_text.begin() + index + clusterCount);
+        auto position = CursorPosition(index);
+        m_cursor = Cursor::collapsed(position);
     }
-    m_text.erase(m_text.begin() + index);
-    auto position = CursorPosition(index);
-    m_cursor = Cursor::collapsed(position);
+    else
+    {
+        // Backspace: erase the full glyph cluster before cursor position.
+        auto index = m_cursor.first().codePointIndex();
+        if (index == 0)
+        {
+            return;
+        }
+        uint32_t clusterStart = glyphLookup.glyphStart(index - 1);
+        uint32_t clusterCount = glyphLookup.count(clusterStart);
+        m_text.erase(m_text.begin() + clusterStart,
+                     m_text.begin() + clusterStart + clusterCount);
+        auto position = CursorPosition(clusterStart);
+        m_cursor = Cursor::collapsed(position);
+    }
     flag(Flags::shapeDirty | Flags::measureDirty | Flags::selectionDirty);
     captureJournalEntry(startingCursor);
 }
@@ -201,17 +222,10 @@
     m_cursorVisualPosition = cursorVisualPosition(m_cursor.end());
 }
 
-RawTextInput::Flags RawTextInput::update(Factory* factory)
+void RawTextInput::ensureShape()
 {
-    Flags updated = Flags::none;
-    if (m_textRun.font == nullptr)
-    {
-        return updated;
-    }
-    bool updateTextPath = false;
     if (unflag(Flags::shapeDirty))
     {
-        updated |= Flags::shapeDirty;
         m_textRun.unicharCount = (uint32_t)m_text.size();
         m_shape.shape(m_text,
                       Span<TextRun>(&m_textRun, 1),
@@ -223,6 +237,21 @@
                       m_origin,
                       m_overflow,
                       m_paragraphSpacing);
+    }
+}
+
+RawTextInput::Flags RawTextInput::update(Factory* factory)
+{
+    Flags updated = Flags::none;
+    if (m_textRun.font == nullptr)
+    {
+        return updated;
+    }
+    bool updateTextPath = false;
+    if (flagged(Flags::shapeDirty))
+    {
+        updated |= Flags::shapeDirty;
+        ensureShape();
         updateTextPath = true;
     }
     if (unflag(Flags::selectionDirty))
@@ -455,6 +484,7 @@
                                     CursorBoundary boundary,
                                     bool select)
 {
+    ensureShape();
     m_idealCursorX = -1.0f;
     CursorPosition end = m_cursor.end();
 
@@ -462,9 +492,28 @@
     switch (boundary)
     {
         case CursorBoundary::character:
-            position =
-                CursorPosition::atIndex(end.codePointIndex(offset), m_shape);
+        {
+            const auto& glyphLookup = m_shape.glyphLookup();
+            uint32_t nextIndex = end.codePointIndex(offset);
+            // Skip over interior codepoints of multi-codepoint glyphs.
+            if (offset > 0)
+            {
+                while (nextIndex < (uint32_t)(m_text.size() - 1) &&
+                       !glyphLookup.isGlyphBoundary(nextIndex))
+                {
+                    nextIndex++;
+                }
+            }
+            else
+            {
+                while (nextIndex > 0 && !glyphLookup.isGlyphBoundary(nextIndex))
+                {
+                    nextIndex--;
+                }
+            }
+            position = CursorPosition::atIndex(nextIndex, m_shape);
             break;
+        }
         case CursorBoundary::line:
         {
             auto line = orderedLine(end);
@@ -656,6 +705,7 @@
 
 void RawTextInput::cursorUp(bool select)
 {
+    ensureShape();
     if (m_idealCursorX == -1.0f)
     {
         m_idealCursorX = m_cursorVisualPosition.x();
@@ -680,6 +730,7 @@
 
 void RawTextInput::cursorDown(bool select)
 {
+    ensureShape();
     if (m_idealCursorX == -1.0f)
     {
         m_idealCursorX = m_cursorVisualPosition.x();
@@ -705,6 +756,7 @@
 
 void RawTextInput::moveCursorTo(Vec2D translation, bool select)
 {
+    ensureShape();
     m_idealCursorX = -1.0f;
     auto position = CursorPosition::fromTranslation(translation, m_shape);
 
diff --git a/src/text/text.cpp b/src/text/text.cpp
index 96d5baf..ebd7928 100644
--- a/src/text/text.cpp
+++ b/src/text/text.cpp
@@ -9,6 +9,9 @@
 #include "rive/text/text_value_run.hpp"
 #include "rive/text/text_modifier_group.hpp"
 #include "rive/shapes/paint/shape_paint.hpp"
+#include "rive/shapes/paint/color.hpp"
+#include "rive/shapes/paint/blend_mode.hpp"
+#include "rive/shapes/paint/image_sampler.hpp"
 #include "rive/viewmodel/viewmodel_instance_string.hpp"
 #include "rive/artboard.hpp"
 #include "rive/factory.hpp"
@@ -189,6 +192,7 @@
         style->rewindPath();
     }
     m_renderStyles.clear();
+    m_drawCommands.clear();
 
     for (TextValueRun* textValueRun : m_allRuns)
     {
@@ -468,8 +472,6 @@
                 GlyphID glyphId = run->glyphs[glyphIndex];
                 float advance = run->advances[glyphIndex];
 
-                RawPath path = font->getPath(glyphId);
-
                 // Step 6.1: translate to the glyph's origin and scale.
                 Vec2D curPos(curX, renderY);
                 float centerX = advance / 2.0f;
@@ -511,21 +513,41 @@
                                          curPos.y + offset.y) *
                     pathTransform;
 
-                path.transformInPlace(pathTransform);
-
                 assert(run->styleId < m_allRuns.size());
                 TextValueRun* textValueRun = m_allRuns[run->styleId];
                 TextStylePaint* style = textValueRun->style();
-                // TextValueRun::onAddedDirty botches loading if it cannot
-                // resolve a style, so we're confident we have a style here.
                 assert(style != nullptr);
 
-                if (style->addPath(path, opacity))
+                // Check for color glyph (emoji) -- draw individually
+                // with per-layer colors instead of accumulating.
+                if (font->isColorGlyph(glyphId))
                 {
-                    // This was the first path added to the style, so let's
-                    // mark it in our draw list.
-                    m_renderStyles.push_back(style);
-                    style->propagateOpacity(renderOpacity());
+                    TextDrawCommand cmd;
+                    cmd.type = TextDrawCommand::kColorGlyph;
+                    cmd.colorGlyph = {run->font,
+                                      glyphId,
+                                      pathTransform,
+                                      style->foregroundColor(),
+                                      opacity};
+                    m_drawCommands.push_back(std::move(cmd));
+                }
+                else
+                {
+                    RawPath path = font->getPath(glyphId);
+                    path.transformInPlace(pathTransform);
+
+                    if (style->addPath(path, opacity))
+                    {
+                        // This was the first path added to the style, so
+                        // let's mark it in our draw list.
+                        m_renderStyles.push_back(style);
+                        style->propagateOpacity(renderOpacity());
+
+                        TextDrawCommand cmd;
+                        cmd.type = TextDrawCommand::kStylePath;
+                        cmd.style = style;
+                        m_drawCommands.push_back(std::move(cmd));
+                    }
                 }
 
                 // Bounds of the glyph
@@ -642,9 +664,16 @@
         renderer->clipPath(m_clipPath.renderPath(this));
     }
     auto worldTransform = shapeWorldTransform();
-    for (auto style : m_renderStyles)
+    for (auto& cmd : m_drawCommands)
     {
-        style->draw(renderer, worldTransform);
+        if (cmd.type == TextDrawCommand::kStylePath)
+        {
+            cmd.style->draw(renderer, worldTransform);
+        }
+        else
+        {
+            drawColorGlyph(renderer, cmd.colorGlyph, worldTransform);
+        }
     }
     if (m_needsSaveOperation)
     {
@@ -652,6 +681,69 @@
     }
 }
 
+void Text::drawColorGlyph(Renderer* renderer,
+                          const TextDrawCommand::ColorGlyphInfo& info,
+                          const Mat2D& worldTransform)
+{
+    std::vector<Font::ColorGlyphLayer> layers;
+    size_t count =
+        info.font->getColorLayers(info.glyphId, layers, info.foregroundColor);
+    if (count == 0)
+    {
+        return;
+    }
+
+    Factory* factory = artboard()->factory();
+    renderer->save();
+    renderer->transform(worldTransform * info.transform);
+
+    for (auto& layer : layers)
+    {
+        if (layer.paintType == Font::ColorGlyphPaintType::image)
+        {
+            // Decode and draw bitmap emoji (SBIX/CBDT).
+            ColorGlyphCacheKey cacheKey{info.font.get(), info.glyphId};
+            auto it = m_emojiImageCache.find(cacheKey);
+            if (it == m_emojiImageCache.end())
+            {
+                auto image = factory->decodeImage(
+                    {layer.imageBytes.data(), layer.imageBytes.size()});
+                it =
+                    m_emojiImageCache.emplace(cacheKey, std::move(image)).first;
+            }
+            if (it->second != nullptr)
+            {
+                renderer->save();
+                // Transform from glyph space: position at bearing and
+                // scale from image pixels to glyph extent units.
+                float scaleX = layer.imageExtentX / (float)layer.imageWidth;
+                float scaleY = layer.imageExtentY / (float)layer.imageHeight;
+                renderer->transform(Mat2D(scaleX,
+                                          0,
+                                          0,
+                                          scaleY,
+                                          layer.imageBearingX,
+                                          layer.imageBearingY));
+                renderer->drawImage(it->second.get(),
+                                    ImageSampler::LinearClamp(),
+                                    BlendMode::srcOver,
+                                    info.opacity);
+                renderer->restore();
+            }
+        }
+        else
+        {
+            auto renderPath =
+                factory->makeRenderPath(layer.path, FillRule::nonZero);
+            auto renderPaint = factory->makeRenderPaint();
+            renderPaint->style(RenderPaintStyle::fill);
+            renderPaint->color(colorModulateOpacity(layer.color, info.opacity));
+            renderer->drawPath(renderPath.get(), renderPaint.get());
+        }
+    }
+    renderer->restore();
+}
+
 void Text::addRun(TextValueRun* run)
 {
     m_runs.push_back(run);
@@ -912,6 +1004,7 @@
         }
         m_orderedLines.clear();
         m_ellipsisRun = {};
+        m_emojiImageCache.clear();
 
         // Immediately build render styles so dimensions get computed.
         buildRenderStyles();
diff --git a/src/text/text_engine.cpp b/src/text/text_engine.cpp
index 68b5852..96aed78 100644
--- a/src/text/text_engine.cpp
+++ b/src/text/text_engine.cpp
@@ -100,11 +100,11 @@
     if (run->dir() == TextDirection::rtl)
     {
         // If the final run is RTL we want to add the length of the final glyph
-        // to get the actual last available code unit in the line.
+        // to get the actual last available codepoint in the line.
         firstCodePointIndex += glyphLookup.count(run->textIndices[glyphIndex]);
     }
     // Clamp ignoring last zero width space for editing.
-    return std::min(firstCodePointIndex, glyphLookup.lastCodeUnitIndex() - 1);
+    return std::min(firstCodePointIndex, glyphLookup.lastCodePointIndex() - 1);
 }
 
 uint32_t OrderedLine::lastCodePointIndex(const GlyphLookup& glyphLookup) const
@@ -127,7 +127,7 @@
         lastCodePointIndex += glyphLookup.count(run->textIndices[glyphIndex]);
     }
     // Clamp ignoring last zero width space for editing.
-    return std::min(lastCodePointIndex, glyphLookup.lastCodeUnitIndex() - 1);
+    return std::min(lastCodePointIndex, glyphLookup.lastCodePointIndex() - 1);
 }
 
 bool OrderedLine::containsCodePointIndex(const GlyphLookup& glyphLookup,
diff --git a/src/text/text_style_paint.cpp b/src/text/text_style_paint.cpp
index d7f210d..877488d 100644
--- a/src/text/text_style_paint.cpp
+++ b/src/text/text_style_paint.cpp
@@ -2,6 +2,8 @@
 #include "rive/text/text.hpp"
 #include "rive/text/text_variation_helper.hpp"
 #include "rive/shapes/paint/shape_paint.hpp"
+#include "rive/shapes/paint/fill.hpp"
+#include "rive/shapes/paint/solid_color.hpp"
 #include "rive/shapes/paint/feather.hpp"
 #include "rive/artboard.hpp"
 #include "rive/factory.hpp"
@@ -98,6 +100,20 @@
     }
 }
 
+ColorInt TextStylePaint::foregroundColor() const
+{
+    for (auto shapePaint : m_ShapePaints)
+    {
+        if (shapePaint->is<Fill>() && shapePaint->paint()->is<SolidColor>())
+        {
+            return (ColorInt)shapePaint->paint()
+                ->as<SolidColor>()
+                ->colorValue();
+        }
+    }
+    return 0xFF000000;
+}
+
 const Mat2D& TextStylePaint::shapeWorldTransform() const
 {
     return parent()->as<Text>()->shapeWorldTransform();
diff --git a/tests/unit_tests/assets/TwemojiMozilla.subset.ttf b/tests/unit_tests/assets/TwemojiMozilla.subset.ttf
new file mode 100644
index 0000000..357dda3
--- /dev/null
+++ b/tests/unit_tests/assets/TwemojiMozilla.subset.ttf
Binary files differ
diff --git a/tests/unit_tests/runtime/color_glyph_test.cpp b/tests/unit_tests/runtime/color_glyph_test.cpp
new file mode 100644
index 0000000..bf9f56b
--- /dev/null
+++ b/tests/unit_tests/runtime/color_glyph_test.cpp
@@ -0,0 +1,489 @@
+#include "catch.hpp"
+#include "rive/text/font_hb.hpp"
+#include "rive/text/raw_text.hpp"
+#include "rive/text/utf.hpp"
+#include "rive/text_engine.hpp"
+#include "utils/no_op_factory.hpp"
+#include "utils/no_op_renderer.hpp"
+#include <string>
+#include <vector>
+
+using namespace rive;
+
+static rcp<Font> loadFont(const char* filename)
+{
+    FILE* fp = fopen(filename, "rb");
+    REQUIRE(fp != nullptr);
+
+    fseek(fp, 0, SEEK_END);
+    const size_t length = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+    std::vector<uint8_t> bytes(length);
+    REQUIRE(fread(bytes.data(), 1, length, fp) == length);
+    fclose(fp);
+
+    return HBFont::Decode(bytes);
+}
+
+static const char* emojiFont = "assets/TwemojiMozilla.subset.ttf";
+
+TEST_CASE("non-emoji font reports no color glyphs", "[color_glyph]")
+{
+    auto font = loadFont("assets/RobotoFlex.ttf");
+    REQUIRE(font != nullptr);
+
+    CHECK_FALSE(font->hasColorGlyphs());
+    // GlyphID 0 is typically .notdef — should not be a color glyph.
+    CHECK_FALSE(font->isColorGlyph(0));
+
+    std::vector<Font::ColorGlyphLayer> layers;
+    size_t count = font->getColorLayers(0, layers);
+    CHECK(count == 0);
+    CHECK(layers.empty());
+}
+
+TEST_CASE("emoji font reports color glyphs", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    CHECK(font->hasColorGlyphs());
+}
+
+TEST_CASE("isColorGlyph returns false for non-color glyph in emoji font",
+          "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    // GlyphID 0 (.notdef) should not be a color glyph even in an emoji font.
+    CHECK_FALSE(font->isColorGlyph(0));
+}
+
+TEST_CASE("known color glyph IDs are detected in subset font", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+    REQUIRE(font->hasColorGlyphs());
+
+    // The TwemojiMozilla.subset.ttf COLR table has base glyphs at IDs 2, 3.
+    CHECK(font->isColorGlyph(2));
+    CHECK(font->isColorGlyph(3));
+}
+
+TEST_CASE("getColorLayers returns layers for a color glyph", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    // Use known color glyph ID from the COLR table.
+    GlyphID colorGlyphId = 2;
+
+    std::vector<Font::ColorGlyphLayer> layers;
+    size_t count = font->getColorLayers(colorGlyphId, layers, 0xFF000000);
+    CHECK(count > 0);
+    CHECK(count == layers.size());
+
+    // Each layer should have a non-empty path.
+    for (const auto& layer : layers)
+    {
+        CHECK(!layer.path.empty());
+        // Color should have full alpha or a palette color.
+        CHECK(((layer.color >> 24) & 0xFF) > 0);
+    }
+}
+
+TEST_CASE("getColorLayers returns empty for non-color glyph", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    std::vector<Font::ColorGlyphLayer> layers;
+    size_t count = font->getColorLayers(0, layers);
+    CHECK(count == 0);
+    CHECK(layers.empty());
+}
+
+TEST_CASE("color glyph layers are cached", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    GlyphID colorGlyphId = 0;
+    for (GlyphID id = 1; id < 100; id++)
+    {
+        if (font->isColorGlyph(id))
+        {
+            colorGlyphId = id;
+            break;
+        }
+    }
+    REQUIRE(colorGlyphId != 0);
+
+    // Call twice — second call should return cached result.
+    std::vector<Font::ColorGlyphLayer> layers1;
+    size_t count1 = font->getColorLayers(colorGlyphId, layers1, 0xFF000000);
+
+    std::vector<Font::ColorGlyphLayer> layers2;
+    size_t count2 = font->getColorLayers(colorGlyphId, layers2, 0xFF000000);
+
+    CHECK(count1 == count2);
+    CHECK(layers1.size() == layers2.size());
+}
+
+TEST_CASE("foreground color is applied for 0xFFFF color index", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    GlyphID colorGlyphId = 0;
+    for (GlyphID id = 1; id < 100; id++)
+    {
+        if (font->isColorGlyph(id))
+        {
+            colorGlyphId = id;
+            break;
+        }
+    }
+    REQUIRE(colorGlyphId != 0);
+
+    // Get layers with two different foreground colors.
+    std::vector<Font::ColorGlyphLayer> layersBlack;
+    font->getColorLayers(colorGlyphId, layersBlack, 0xFF000000);
+
+    std::vector<Font::ColorGlyphLayer> layersRed;
+    font->getColorLayers(colorGlyphId, layersRed, 0xFFFF0000);
+
+    // The number of layers should be the same.
+    REQUIRE(layersBlack.size() == layersRed.size());
+
+    // Check if any layer uses the foreground color by seeing if colors differ
+    // between the two calls (layers that use foreground will differ).
+    bool hasForegroundLayer = false;
+    for (size_t i = 0; i < layersBlack.size(); i++)
+    {
+        if (layersBlack[i].useForeground)
+        {
+            hasForegroundLayer = true;
+            CHECK(layersBlack[i].color == 0xFF000000);
+            CHECK(layersRed[i].color == 0xFFFF0000);
+        }
+    }
+    // Not all fonts use foreground layers, so this is informational.
+    (void)hasForegroundLayer;
+}
+
+TEST_CASE("withOptions preserves color glyph support", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+    CHECK(font->hasColorGlyphs());
+
+    // Create a sub-font with no option changes — should still report color.
+    auto subFont = font->withOptions({}, {});
+    REQUIRE(subFont != nullptr);
+    CHECK(subFont->hasColorGlyphs());
+}
+
+TEST_CASE("RawText renders with color glyph font without crashing",
+          "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    NoOpFactory factory;
+    RawText rawText(&factory);
+    rawText.maxWidth(200.0f);
+    rawText.sizing(TextSizing::autoHeight);
+
+    // Append text — the emoji font may or may not have Latin glyphs,
+    // but it should not crash regardless.
+    rawText.append("A", nullptr, font, 32.0f);
+
+    NoOpRenderer renderer;
+    rawText.render(&renderer);
+}
+
+// ---------- shaping tests ----------
+
+static rive::TextRun appendText(std::vector<rive::Unichar>* unichars,
+                                rive::rcp<rive::Font> font,
+                                float size,
+                                const char text[])
+{
+    const uint8_t* ptr = (const uint8_t*)text;
+    uint32_t n = 0;
+    while (*ptr)
+    {
+        unichars->push_back(rive::UTF::NextUTF8(&ptr));
+        n += 1;
+    }
+    return {std::move(font), size, -1.0f, 0.0f, n, 0};
+}
+
+TEST_CASE("shaping emoji font produces glyphs", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    std::vector<rive::Unichar> unichars;
+    std::vector<rive::TextRun> truns;
+    truns.push_back(appendText(&unichars, font, 32.0f, "A"));
+
+    auto paragraphs = font->shapeText(unichars, truns);
+    REQUIRE(paragraphs.size() == 1);
+    REQUIRE(paragraphs[0].runs.size() >= 1);
+
+    // At least one glyph should be produced without crashing.
+    const auto& run = paragraphs[0].runs[0];
+    CHECK(run.glyphs.size() > 0);
+}
+
+TEST_CASE("shaping with fallback uses emoji font for missing glyphs",
+          "[color_glyph]")
+{
+    auto regularFont = loadFont("assets/RobotoFlex.ttf");
+    REQUIRE(regularFont != nullptr);
+    auto emojiFontRcp = loadFont(emojiFont);
+    REQUIRE(emojiFontRcp != nullptr);
+
+    // Set up fallback proc.
+    static rive::rcp<rive::Font> sFallback;
+    sFallback = emojiFontRcp;
+    Font::gFallbackProc = [](const rive::Unichar,
+                             const uint32_t fallbackIndex,
+                             const rive::Font*) -> rive::rcp<rive::Font> {
+        if (fallbackIndex > 0)
+            return nullptr;
+        return sFallback;
+    };
+
+    std::vector<rive::Unichar> unichars;
+    std::vector<rive::TextRun> truns;
+    // "A❤B" — A and B from regular, ❤ should fallback to emoji font.
+    truns.push_back(appendText(&unichars,
+                               regularFont,
+                               32.0f,
+                               "A\xe2\x9d\xa4"
+                               "B"));
+
+    auto paragraphs = regularFont->shapeText(unichars, truns);
+    REQUIRE(paragraphs.size() == 1);
+
+    // Should produce multiple runs due to font fallback.
+    // The fallback font is an emoji font, so it should be used for
+    // the missing glyph. At minimum, we verify shaping doesn't crash
+    // and produces runs.
+    bool foundEmojiFont = false;
+    for (const auto& run : paragraphs[0].runs)
+    {
+        if (run.font->hasColorGlyphs())
+        {
+            foundEmojiFont = true;
+        }
+    }
+    CHECK(foundEmojiFont);
+
+    Font::gFallbackProc = nullptr;
+    sFallback = nullptr;
+}
+
+// ---------- COLRv0 layer detail tests ----------
+
+TEST_CASE("COLRv0 layers have solid paint type", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    std::vector<Font::ColorGlyphLayer> layers;
+    size_t count = font->getColorLayers(2, layers, 0xFF000000);
+    REQUIRE(count > 0);
+
+    for (const auto& layer : layers)
+    {
+        // COLRv0 always produces solid fill layers.
+        CHECK(layer.paintType == Font::ColorGlyphPaintType::solid);
+        // Gradient data should be unused.
+        CHECK(layer.stops.empty());
+        // Image data should be unused.
+        CHECK(layer.imageBytes.empty());
+    }
+}
+
+TEST_CASE("all known color glyph IDs return layers", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    // Both glyph IDs 2 and 3 should produce layers.
+    for (GlyphID id : {(GlyphID)2, (GlyphID)3})
+    {
+        std::vector<Font::ColorGlyphLayer> layers;
+        size_t count = font->getColorLayers(id, layers, 0xFF000000);
+        CHECK(count > 0);
+        CHECK(count == layers.size());
+    }
+}
+
+TEST_CASE("cached layers update foreground color correctly", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    GlyphID id = 2;
+    // Prime the cache with black foreground.
+    std::vector<Font::ColorGlyphLayer> layersFirst;
+    font->getColorLayers(id, layersFirst, 0xFF000000);
+
+    // Now request with green foreground — cached layers should reflect this.
+    std::vector<Font::ColorGlyphLayer> layersGreen;
+    font->getColorLayers(id, layersGreen, 0xFF00FF00);
+
+    REQUIRE(layersFirst.size() == layersGreen.size());
+
+    for (size_t i = 0; i < layersFirst.size(); i++)
+    {
+        if (layersFirst[i].useForeground)
+        {
+            CHECK(layersFirst[i].color == 0xFF000000);
+            CHECK(layersGreen[i].color == 0xFF00FF00);
+        }
+        else
+        {
+            // Non-foreground layers should be identical.
+            CHECK(layersFirst[i].color == layersGreen[i].color);
+        }
+    }
+}
+
+TEST_CASE("getColorLayers returns zero for non-color font", "[color_glyph]")
+{
+    auto font = loadFont("assets/RobotoFlex.ttf");
+    REQUIRE(font != nullptr);
+
+    // Try several glyph IDs — none should be color.
+    for (GlyphID id = 0; id < 10; id++)
+    {
+        std::vector<Font::ColorGlyphLayer> layers;
+        size_t count = font->getColorLayers(id, layers, 0xFF000000);
+        CHECK(count == 0);
+        CHECK(layers.empty());
+    }
+}
+
+TEST_CASE("getColorLayers appends to existing vector", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    std::vector<Font::ColorGlyphLayer> layers;
+    size_t count1 = font->getColorLayers(2, layers, 0xFF000000);
+    REQUIRE(count1 > 0);
+    CHECK(layers.size() == count1);
+
+    // Append layers for another glyph into the same vector.
+    size_t count2 = font->getColorLayers(3, layers, 0xFF000000);
+    REQUIRE(count2 > 0);
+    CHECK(layers.size() == count1 + count2);
+}
+
+TEST_CASE("isColorGlyph is false for high glyph IDs", "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    // Very high glyph IDs that don't exist should not crash and return false.
+    CHECK_FALSE(font->isColorGlyph(9999));
+    CHECK_FALSE(font->isColorGlyph(65535));
+}
+
+// ---------- RawText rendering tests with color glyphs ----------
+
+TEST_CASE("RawText with multiple color glyphs renders without crashing",
+          "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    NoOpFactory factory;
+    RawText rawText(&factory);
+    rawText.maxWidth(400.0f);
+    rawText.sizing(TextSizing::autoHeight);
+
+    // Append the same character multiple times.
+    rawText.append("\xe2\x9d\xa4\xe2\x9d\xa4\xe2\x9d\xa4",
+                   nullptr,
+                   font,
+                   32.0f);
+
+    NoOpRenderer renderer;
+    rawText.render(&renderer);
+}
+
+TEST_CASE("RawText with mixed regular and emoji text renders without crashing",
+          "[color_glyph]")
+{
+    auto regularFont = loadFont("assets/RobotoFlex.ttf");
+    REQUIRE(regularFont != nullptr);
+    auto emojiFontRcp = loadFont(emojiFont);
+    REQUIRE(emojiFontRcp != nullptr);
+
+    // Set up fallback.
+    static rive::rcp<rive::Font> sFallback;
+    sFallback = emojiFontRcp;
+    Font::gFallbackProc = [](const rive::Unichar,
+                             const uint32_t fallbackIndex,
+                             const rive::Font*) -> rive::rcp<rive::Font> {
+        if (fallbackIndex > 0)
+            return nullptr;
+        return sFallback;
+    };
+
+    NoOpFactory factory;
+    RawText rawText(&factory);
+    rawText.maxWidth(400.0f);
+    rawText.sizing(TextSizing::autoHeight);
+
+    // Mix of regular Latin text and an emoji character.
+    rawText.append("Hello \xe2\x9d\xa4 World", nullptr, regularFont, 32.0f);
+
+    NoOpRenderer renderer;
+    rawText.render(&renderer);
+
+    Font::gFallbackProc = nullptr;
+    sFallback = nullptr;
+}
+
+TEST_CASE("RawText at small font size with emoji does not crash",
+          "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    NoOpFactory factory;
+    RawText rawText(&factory);
+    rawText.maxWidth(100.0f);
+    rawText.sizing(TextSizing::autoHeight);
+
+    rawText.append("\xe2\x9d\xa4", nullptr, font, 1.0f);
+
+    NoOpRenderer renderer;
+    rawText.render(&renderer);
+}
+
+TEST_CASE("RawText at large font size with emoji does not crash",
+          "[color_glyph]")
+{
+    auto font = loadFont(emojiFont);
+    REQUIRE(font != nullptr);
+
+    NoOpFactory factory;
+    RawText rawText(&factory);
+    rawText.maxWidth(2000.0f);
+    rawText.sizing(TextSizing::autoHeight);
+
+    rawText.append("\xe2\x9d\xa4", nullptr, font, 200.0f);
+
+    NoOpRenderer renderer;
+    rawText.render(&renderer);
+}
diff --git a/tests/unit_tests/runtime/raw_text_input_test.cpp b/tests/unit_tests/runtime/raw_text_input_test.cpp
index 608e1e2..992c421 100644
--- a/tests/unit_tests/runtime/raw_text_input_test.cpp
+++ b/tests/unit_tests/runtime/raw_text_input_test.cpp
@@ -484,6 +484,134 @@
     CHECK(textInput.cursor().start().codePointIndex() == 20);
 }
 
+TEST_CASE("cursor skips multi-codepoint glyphs", "[text_input]")
+{
+    auto font = loadFont("assets/fonts/Inter_18pt-Regular.ttf");
+
+    RawTextInput textInput;
+    // "cafe\u0301s" = "cafés" where é = e + combining acute accent (2
+    // codepoints, 1 glyph)
+    // Indices: c=0 a=1 f=2 e=3 \u0301=4 s=5
+    std::string defaultText =
+        "caf\xC3\xA9s"; // UTF-8 for café with precomposed é
+    // Actually we need the decomposed form: e + combining acute accent
+    // e = 0x65, combining acute = 0xCC 0x81 in UTF-8
+    defaultText = "cafe\xCC\x81s";
+    textInput.insert(defaultText);
+    textInput.cursor(Cursor::zero());
+    textInput.font(font);
+    textInput.fontSize(72.0f);
+
+    NoOpFactory factory;
+    textInput.update(&factory);
+
+    // Move right: c(0) -> a(1) -> f(2) -> e(3) -> s(5) (should skip index 4)
+    textInput.cursorRight();
+    textInput.update(&factory);
+    CHECK(textInput.cursor().start().codePointIndex() == 1);
+
+    textInput.cursorRight();
+    textInput.update(&factory);
+    CHECK(textInput.cursor().start().codePointIndex() == 2);
+
+    textInput.cursorRight();
+    textInput.update(&factory);
+    CHECK(textInput.cursor().start().codePointIndex() == 3);
+
+    textInput.cursorRight();
+    textInput.update(&factory);
+    // Should skip index 4 (combining accent) and land on 5
+    CHECK(textInput.cursor().start().codePointIndex() == 5);
+}
+
+TEST_CASE("cursor left skips multi-codepoint glyphs", "[text_input]")
+{
+    auto font = loadFont("assets/fonts/Inter_18pt-Regular.ttf");
+
+    RawTextInput textInput;
+    std::string defaultText = "cafe\xCC\x81s";
+    textInput.insert(defaultText);
+    textInput.cursor(Cursor::zero());
+    textInput.font(font);
+    textInput.fontSize(72.0f);
+
+    NoOpFactory factory;
+    textInput.update(&factory);
+
+    // Go to end
+    textInput.cursorDown();
+    textInput.update(&factory);
+
+    // Move left from end(6) -> s(5) -> é(3) (skip 4) -> f(2)
+    textInput.cursorLeft();
+    textInput.update(&factory);
+    CHECK(textInput.cursor().start().codePointIndex() == 5);
+
+    textInput.cursorLeft();
+    textInput.update(&factory);
+    // Should skip index 4 and land on 3
+    CHECK(textInput.cursor().start().codePointIndex() == 3);
+
+    textInput.cursorLeft();
+    textInput.update(&factory);
+    CHECK(textInput.cursor().start().codePointIndex() == 2);
+}
+
+TEST_CASE("backspace deletes entire multi-codepoint glyph", "[text_input]")
+{
+    auto font = loadFont("assets/fonts/Inter_18pt-Regular.ttf");
+
+    RawTextInput textInput;
+    std::string defaultText = "cafe\xCC\x81s";
+    textInput.insert(defaultText);
+    textInput.cursor(Cursor::zero());
+    textInput.font(font);
+    textInput.fontSize(72.0f);
+
+    NoOpFactory factory;
+    textInput.update(&factory);
+
+    // Move cursor to after the é (before 's')
+    textInput.cursorDown();
+    textInput.update(&factory);
+    textInput.cursorLeft(); // at 's' = index 5
+    textInput.update(&factory);
+    CHECK(textInput.cursor().start().codePointIndex() == 5);
+
+    // Backspace should delete both codepoints of é (indices 3 and 4)
+    textInput.backspace(-1);
+    textInput.update(&factory);
+    CHECK(textInput.text() == "cafs");
+    CHECK(textInput.cursor().start().codePointIndex() == 3);
+}
+
+TEST_CASE("delete forward removes entire multi-codepoint glyph", "[text_input]")
+{
+    auto font = loadFont("assets/fonts/Inter_18pt-Regular.ttf");
+
+    RawTextInput textInput;
+    std::string defaultText = "cafe\xCC\x81s";
+    textInput.insert(defaultText);
+    textInput.cursor(Cursor::zero());
+    textInput.font(font);
+    textInput.fontSize(72.0f);
+
+    NoOpFactory factory;
+    textInput.update(&factory);
+
+    // Move cursor to before the é (after 'f') = index 3
+    textInput.cursorRight();
+    textInput.cursorRight();
+    textInput.cursorRight();
+    textInput.update(&factory);
+    CHECK(textInput.cursor().start().codePointIndex() == 3);
+
+    // Delete forward should remove both codepoints of é
+    textInput.backspace(1);
+    textInput.update(&factory);
+    CHECK(textInput.text() == "cafs");
+}
+
 #define CHECK_CURSOR(A, START, END)                                            \
     CHECK(A.start().codePointIndex() == START);                                \
     CHECK(A.end().codePointIndex() == END)
diff --git a/tests/unit_tests/silvers/text_stroke_test.sriv b/tests/unit_tests/silvers/text_stroke_test.sriv
index 4a593a4..c58ac32 100644
--- a/tests/unit_tests/silvers/text_stroke_test.sriv
+++ b/tests/unit_tests/silvers/text_stroke_test.sriv
Binary files differ