Compare commits

..
13 Commits
Author SHA1 Message Date
Bitsy 275ee97d56 fix(publish): :sdl-core emits a publishable klib + harden retry-cleanup jq
v0.4.0 publish failed on all hosts at :sdl-core:generateMetadataFileFor<Target>Publication
(FileNotFound on sdl-core-<target>Main-<ver>.klib). Root cause: :sdl-core is a
cinterop-only module with ZERO Kotlin sources, so the native main compilation
emits no main klib for maven-publish to consume. Add a minimal internal marker
in nativeMain so every target produces a klib; the sdl3 cinterop klib +.module
metadata ride along (verified via publishMingwX64PublicationToMavenLocal across
all modules).

Also harden cleanup_host_versions' jq: a not-yet-published package returns a
JSON object, not an array, which crashed 'select(.name==$v)' ('Cannot index
string with string') and defeated the retry-cleanup. Guard with type=="array".
2026-07-26 01:04:26 +02:00
Bitsy e5fb04f882 chore(api): refresh klib baselines + exclude sdl-core/material-symbols; add regen to release runbook
Regenerated all tracked klib API dumps (they'd drifted — stale bodies from
before the module split/rename). Exclude :sdl-core (naked SDL cinterop — its
API is the generated sdl3.* bindings, per-OS, not our surface) and
:material-symbols (auto-generated icon codepoint maps; its jvm dump also trips
BCV's ASM on JDK 25, 'class file major version 69') from apiValidation.
macosArm64 is inferred from the linux/mingw ABIs (accurate for the
target-independent Compose surface). Documented 'regenerate baselines before
tagging' in the release runbook; not a hard apiCheck gate until the API
stabilizes. Also fixed two stale com.bitsycore.compose.sdl coord refs in the
TOOLING version map / publish notes (now per-area).
2026-07-26 00:55:04 +02:00
Bitsy 23849330d1 docs(api): regenerate desktop-native-window API dump
The checked-in baseline was stale — generated very early (package
com.compose.desktop.native, only nativeComposeWindow public) and never
regenerated since; the coord rebrand only patched its header. Now that mingw
builds (skiko fork published), apiDump reflects the real surface: nativeComposeApp,
ApplicationScope.Window, AppWindowIcon, windowHasInvalidations, the frame-time
toggles, and the updated nativeComposeWindow signature — all in com.compose.sdl.
2026-07-26 00:45:25 +02:00
Bitsy 4272cec614 refactor(coords): per-area com.bitsycore groups, :window → :desktop-native-window, skiko fork → com.bitsycore.skiko
Rebrand the fork's published coordinates as the 1:1 com.bitsycore mirror of
their org.jetbrains originals, so each module is an obvious fork under the
bitsycore name:
- Per-area groups: com.bitsycore.compose.sdl:<mod> → com.bitsycore.compose.<area>:<mod>
  (ui / foundation / animation / material3 / material / components / navigation3),
  mirroring org.jetbrains.compose.<area>. Project-only modules (:sdl-core,
  :material-symbols) stay com.bitsycore.compose.sdl. Driven by a groupFor() map
  in root build.gradle.kts; the kUseGhPackages substitution + the consumer bridge
  plugin's bridgeTable now emit full per-area coords; publish.yml host_packages
  maps each module to its group (+ adds the split modules to the MODULES list).
- :window renamed to :desktop-native-window (dir compose/sdl/window →
  compose/desktop/native/window; sdl/ now holds only :sdl-core). Published as the
  headline app-shell artifact com.bitsycore.compose:desktop-native-window.
- Consumed skiko mingw fork org.jetbrains.skiko:skiko(+skiko-mingwx64) →
  com.bitsycore.skiko (ui/ui-graphics/ui-text + the DLL provisioner); settings
  repo filters updated. The OFFICIAL skiko (macOS/Linux libs.skiko) and the
  skiko-awt-runtime icudtl source stay org.jetbrains; the fork keeps upstream's
  org.jetbrains.skiko.* PACKAGE names — only the Maven coord is rebranded.
- Docs (CLAUDE/README/TOOLING/RENDERER/bridge README) + stale :window comments
  swept; API dump unique-name headers patched to the new groups + the window dump
  renamed (API is pre-stable; dumps regen once the build can run).

BLOCKED: mingwX64 build + publish need the bitsycore/skiko fork repo to
republish under com.bitsycore.skiko first. Verified locally: bridge plugin
compiles, main build configures, project tree resolves to the new paths.
2026-07-25 23:29:44 +02:00
Bitsy 3f4b3a23be docs+cleanup: refresh module-layout docs and purge dead SDL-renderer references after the :sdl-core / :ui-graphics / :ui-text split
- Regenerate API dumps: ui.klib.api drops the ui.graphics.*/ui.text.* surface
  (now carried by the new ui-graphics/ui-text dumps).
- components-resources: fold the historically-named src/sdlRendererMain dir into
  src/nativeMain (rename *.sdl.kt -> *.native.kt); drop the extra srcDir; fix the
  SDL3_image/IMG_LoadSVG comments (decode is Skia via the :ui-graphics hook).
- Purge stale two-renderer / SDL3_ttf / SDL3_image / FreeType / -Prenderer=sdl3
  references from live comments (RenderBackendFactory, IconFont, IconFontIcon,
  WindowIcon, PlatformClipboard, MaterialSymbolsScreen, sdl3.def, build-all.py,
  make-app-icon.py) and CLAUDE.md rule 4.
- verify-mac.sh: drop the removed SDL-renderer leg from the header prose.
- Keep the accurate 'were removed / no longer built' historical notes.

Comment/doc + build-file-comment changes plus the components-resources dir
rename; no executable logic changed. Verified: :components-resources compile +
metadata gate + :demo/:apidemo mingw build all green.
2026-07-25 22:57:23 +02:00
Bitsy d058f1b6a2 refactor(cleanup): delete dead Project* render cluster + fix bridge for the ui split
- Delete the ~920-line dead cluster superseded by the vendored SkiaBacked* actuals:
  ProjectCanvas/Paint/Path/PathIterator/ImageBitmap, Offscreen (OffscreenRenderer),
  SkiaDrawScope — a self-referential island with zero live references (RENDERER.md
  B6.2's deferred deletion, finally done).
- Full-commonization bridge (root build.gradle + the consumer bridge plugin): the
  official ui-graphics / ui-text coords now substitute to the NEW :ui-graphics /
  :ui-text modules (were still routed to :ui). Added :sdl-core / :ui-graphics /
  :ui-text to kPublishedLibs so they publish + the consumer plugin can map them.

Verified: demo + apidemo compileCommonMainKotlinMetadata + demo link green.
2026-07-25 22:32:33 +02:00
Bitsy 924ebe9776 refactor(ui): split :ui-text out of :ui — completes the upstream ui layout
androidx.compose.ui.text.* + the B6.3 skiko text engine (SkiaParagraph / SkiaParagraphOps
/ SkiaFonts, IconFont, NamedFont, ParagraphFactories, Locale/font actuals) now live in
:ui-text — deps :ui-graphics + skiko, SDL-free. :ui -> :ui-text (api). :ui is now the
Compose core + renderer on top of :ui-graphics / :ui-text / :sdl-core, mirroring upstream.

- compose-fork.txt: the ui-text SET_FOLDER section moved to :ui-text's own manifest;
  re-synced (95 vendored files).
- SystemLocale (SDL) / GenericFonts (resource glue) / ImeBridge stay in :ui;
  Locale/PlatformLocale (text.intl actuals) read the OS locale via a new
  preferredLocaleTagsProvider seam that SystemLocale installs.
- Made cross-module decls public (NoOpPlatformTextInputService); :ui-text needs
  runtime-saveable (Savers).

Verified mingw compile + compileCommonMainKotlinMetadata + demo render (Material Symbols:
variable-font axes + text correct).
2026-07-25 22:10:33 +02:00
Bitsy 5dc4b21867 refactor(ui): split :ui-graphics out of :ui (upstream layout)
androidx.compose.ui.graphics.* + the Skia actuals (SkiaBackedCanvas, SkiaImageCache,
GraphicsLayer/Context, painter/image seams) now live in :ui-graphics — deps skiko +
:ui-geometry/unit/util, SDL-free (image bytes via the composeResourceReader seam).
:ui -> :ui-graphics (api). Mirrors upstream's ui/ui-graphics split: each module is
self-contained (graphics expects + skiko actuals same module), so no cross-module
expect/actual and compileCommonMainKotlinMetadata stays green.

- compose-fork.txt split: the ui-graphics SET_FOLDER section moved to :ui-graphics's
  own manifest; re-synced (99 vendored files).
- Broke the one ui-core coupling: drawNativePainter / SkiaImageCache no longer take
  ContentScale (upstream PainterModifier pre-scales the destination, so the painter
  draws fill-bounds) — Fit/Crop/FillBounds still render correctly.
- Made the cross-module decls public (SkiaImageCache / SkiaLeafDrawer / GraphicsContext /
  readBackBgra / encodedImageDecoder setter / prepareLayerTransformationMatrix).

Verified mingw compile + metadata + demo render.
2026-07-25 22:01:56 +02:00
Bitsy accd74c9ee refactor(sdl): move the sdl3 cinterop into :sdl-core (Phase 1.2a)
New :sdl-core module (sdl/sdl-core) owns the single sdl3 cinterop; :ui exposes it
via api(project(":sdl-core")). Proves cross-module cinterop works: :ui sees
sdl3.*, and SDL3's static lib + linker opts propagate through the klib chain to
the final exe (SDL auto-links just by depending on :ui, unchanged). :sdl-core has
no :ui dependency, so :ui -> :sdl-core introduces no cycle.

Next: move the SDL platform + Skia renderer from :ui into :sdl-core (flips to
:sdl-core -> :ui, makes :ui SDL-free), then split ui-graphics/ui-text. Verified
on mingw (Widgets: controls + text + input all work).
2026-07-25 21:00:14 +02:00
Bitsy 30cc39606a refactor(sdl): platform-env seam — decouple foundation + resources from cinterop (Phase 1.1)
DarkTheme (:foundation, isSystemInDarkTheme) and ResourceEnvironment
(:components-resources, locale/theme qualifiers) called the sdl3 cinterop
directly (SDL_GetSystemTheme / SDL_GetPreferredLocales). Route them through a new
com.compose.sdl.res.{systemThemeIsDarkProvider,preferredLocaleProvider} seam that
SDL3Backend.init() installs. Now only the SDL layer + :window import sdl3 — the
prerequisite for relocating the cinterop into :sdl-core without those modules
needing it. Verified on mingw.
2026-07-25 20:51:24 +02:00
Bitsy 099211b015 refactor(ui): resource-bytes seam — decouple font/image loading from SDL (Phase 0)
SkiaFonts (fonts) + SkiaImageCache (images) read bundled bytes through a new
com.compose.sdl.res.composeResourceReader seam instead of calling
loadComposeResourceBytes (which uses the sdl3 cinterop via SDL_GetBasePath)
directly. SkiaRenderBackend installs the SDL-backed impl at construction. This is
the enabler for splitting ui-graphics/ui-text out of :ui without an SDL cinterop
dependency. Also deletes the throwaway ParagraphSpike + --paraspike demo flag.
Verified on mingw (Images screen: fonts + PNG/JPG/SVG/Android-XML all render).
2026-07-25 20:40:52 +02:00
Bitsy 37a44ffb46 fix(ci): bundle skiko-windows-x64.dll + icudtl.dat in the mingwX64 zips
The release zip step packaged only <app>.exe + data.kres, so the Windows binary
shipped without the two runtime sidecars the bridge plugin provisions next to the
exe (the skiko fork DLL + Skia's ICU data). The mingw exe cannot run without them.
Include both for the exe target (fail loudly if a provision ever regresses);
macOS/Linux unaffected. (v0.3.1 mingw zips need this — patch manually or re-tag.)
2026-07-25 20:09:17 +02:00
Bitsy 045c734eef fix(apidemo): wrappedRowCount via Paragraph.lineCount (currentTextMeasurer removed)
The B6.3 cleanup deleted com.compose.sdl.text.currentTextMeasurer, but apidemo's
Compat.native.kt still used it for wrappedRowCount. Rebuild it on the standard
Paragraph factory (skiko lineCount) — same physical-pixel space (density 1,
fontSize=inFontPx.sp, wrap at inMaxWidthPx). Fixes the v0.3.0 'Build demo +
apidemo release binaries' step, which failed on all targets after the library
publish step had already succeeded.
2026-07-25 19:30:04 +02:00
131 changed files with 6032 additions and 15367 deletions
+44 -21
View File
@@ -103,16 +103,13 @@ jobs:
# intrinsic K/N's LLD can't resolve is aliased to msvcrt's _setjmpex at # intrinsic K/N's LLD can't resolve is aliased to msvcrt's _setjmpex at
# link time via --defsym in sdl3.def. # link time via --defsym in sdl3.def.
# Build the static native deps from scripts/build-sdl/build-sdl.properties. # Build the static SDL3 lib (scripts/build-sdl/build-sdl.properties). Every
# Only Windows ships the SDL3 renderer (no Skiko on mingw), so only it needs # target renders through Skia now, so all platforms need only base SDL3 for
# SDL3_ttf / SDL3_image / FreeType (SDL3_ttf text, SDL3_image decode, FreeType # the main loop (windowing / input / audio / filesystem) — the from-scratch
# icon-axis rasterisation). macOS / Linux publish the Skia renderer — Skiko # SDL renderer and its SDL3_ttf / SDL3_image / FreeType deps were removed.
# handles text / images / icons — so they only need base SDL3 for the main # Cached against the manifest + scripts so version bumps invalidate cleanly;
# loop (windowing / input / audio / filesystem). Matches the cinterop guard # bump the `v3` key when the toolchain (runner OS, compiler flavour, K/N
# in compose/ui/ui/build.gradle.kts, which skips those three cinterops on the # sysroot) changes without a scripts/build-sdl/ edit.
# Skia targets. Cached against the manifest + scripts so version bumps
# invalidate cleanly; bump the `v3` key when the toolchain (runner OS,
# compiler flavour, K/N sysroot) changes without a scripts/build-sdl/ edit.
- name: Cache libs/ - name: Cache libs/
id: cache-libs id: cache-libs
uses: actions/cache@v4 uses: actions/cache@v4
@@ -120,16 +117,10 @@ jobs:
path: libs path: libs
key: sdl-libs-v3-${{ matrix.host }}-${{ hashFiles('scripts/build-sdl/**') }} key: sdl-libs-v3-${{ matrix.host }}-${{ hashFiles('scripts/build-sdl/**') }}
# Windows: full SDL3 renderer stack. macOS / Linux (Skia): base SDL3 only.
- name: Build static native deps - name: Build static native deps
if: steps.cache-libs.outputs.cache-hit != 'true' if: steps.cache-libs.outputs.cache-hit != 'true'
shell: bash shell: bash
run: | run: python3 scripts/build-sdl/build-all.py
if [ "${{ matrix.host }}" = "windows" ]; then
python3 scripts/build-sdl/build-all.py
else
python3 scripts/build-sdl/build-all.py sdl3
fi
# src/vendor/ trees are gitignored — a fresh checkout has zero vendored # src/vendor/ trees are gitignored — a fresh checkout has zero vendored
# androidx.compose.* files. Sync copies them in from the upstream refs # androidx.compose.* files. Sync copies them in from the upstream refs
@@ -160,16 +151,35 @@ jobs:
VER="${PUBLISH_VERSION#v}" VER="${PUBLISH_VERSION#v}"
OWNER="${GITHUB_REPOSITORY%%/*}" OWNER="${GITHUB_REPOSITORY%%/*}"
# Keep in sync with the module list in settings.gradle.kts. # Keep in sync with the module list in settings.gradle.kts.
MODULES="ui ui-util ui-geometry ui-unit ui-backhandler ui-tooling-preview animation animation-core animation-graphics foundation foundation-layout material3 material-ripple window material-symbols navigation3-ui components-resources" MODULES="sdl-core ui ui-graphics ui-text ui-util ui-geometry ui-unit ui-backhandler ui-tooling-preview animation animation-core animation-graphics foundation foundation-layout material3 material-ripple desktop-native-window material-symbols navigation3-ui components-resources"
case "${{ matrix.host }}" in case "${{ matrix.host }}" in
macos) SUFFIXES="-macosarm64" ;; macos) SUFFIXES="-macosarm64" ;;
linux) SUFFIXES="-linuxx64 -linuxarm64" ;; linux) SUFFIXES="-linuxx64 -linuxarm64" ;;
windows) SUFFIXES="_ROOT_ -mingwx64" ;; windows) SUFFIXES="_ROOT_ -mingwx64" ;;
esac esac
# Published group per module — mirrors the per-area com.bitsycore groups
# in root build.gradle.kts. Project-only modules (sdl-core, material-symbols)
# fall through to com.bitsycore.compose.sdl; the GitHub Packages Maven
# package name is "<group>.<artifact>".
group_of() {
case "$1" in
ui|ui-graphics|ui-text|ui-util|ui-geometry|ui-unit|ui-backhandler|ui-tooling-preview)
echo "com.bitsycore.compose.ui" ;;
foundation|foundation-layout) echo "com.bitsycore.compose.foundation" ;;
animation|animation-core|animation-graphics) echo "com.bitsycore.compose.animation" ;;
material3) echo "com.bitsycore.compose.material3" ;;
material-ripple) echo "com.bitsycore.compose.material" ;;
components-resources) echo "com.bitsycore.compose.components" ;;
navigation3-ui) echo "com.bitsycore.navigation3" ;;
desktop-native-window) echo "com.bitsycore.compose" ;;
*) echo "com.bitsycore.compose.sdl" ;;
esac
}
host_packages() { host_packages() {
for m in $MODULES; do for m in $MODULES; do
g=$(group_of "$m")
for s in $SUFFIXES; do for s in $SUFFIXES; do
if [ "$s" = "_ROOT_" ]; then echo "com.bitsycore.compose.sdl.$m"; else echo "com.bitsycore.compose.sdl.$m$s"; fi if [ "$s" = "_ROOT_" ]; then echo "$g.$m"; else echo "$g.$m$s"; fi
done done
done done
if [ "${{ matrix.host }}" = "windows" ]; then if [ "${{ matrix.host }}" = "windows" ]; then
@@ -183,7 +193,7 @@ jobs:
host_packages | while read -r pkg; do host_packages | while read -r pkg; do
vid=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ vid=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
"https://api.github.com/users/$OWNER/packages/maven/$pkg/versions?per_page=100" \ "https://api.github.com/users/$OWNER/packages/maven/$pkg/versions?per_page=100" \
| jq -r --arg v "$VER" '[.[]? | select(.name==$v) | .id] | first // empty') | jq -r --arg v "$VER" 'if type=="array" then ([.[] | select(.name==$v) | .id] | first // empty) else empty end')
[ -z "$vid" ] && continue [ -z "$vid" ] && continue
code=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \ code=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
-H "Authorization: Bearer $GITHUB_TOKEN" \ -H "Authorization: Bearer $GITHUB_TOKEN" \
@@ -242,8 +252,21 @@ jobs:
for app in demo apidemo; do for app in demo apidemo; do
src="$app/build/bin/$target_dir/releaseExecutable" src="$app/build/bin/$target_dir/releaseExecutable"
zip_path="$(pwd)/dist/$app-$version-$target_dir.zip" zip_path="$(pwd)/dist/$app-$version-$target_dir.zip"
files=("$src/$app.${{ matrix.exe_ext }}" "$src/data.kres")
# Windows Skia leg ships two runtime sidecars next to the exe — the
# skiko fork DLL and Skia's ICU data (icudtl.dat) — provisioned by the
# bridge plugin after linkReleaseExecutableMingwX64. The exe cannot run
# without them, so include them (and fail loudly if a provision regressed).
if [ "${{ matrix.exe_ext }}" = "exe" ]; then
for sidecar in skiko-windows-x64.dll icudtl.dat; do
if [ ! -f "$src/$sidecar" ]; then
echo "::error::Missing Windows runtime sidecar: $src/$sidecar"; exit 1
fi
files+=("$src/$sidecar")
done
fi
python3 -c 'import sys,os,zipfile; z=zipfile.ZipFile(sys.argv[1],"w",zipfile.ZIP_DEFLATED,compresslevel=9); [z.write(f,os.path.basename(f)) for f in sys.argv[2:]]; z.close()' \ python3 -c 'import sys,os,zipfile; z=zipfile.ZipFile(sys.argv[1],"w",zipfile.ZIP_DEFLATED,compresslevel=9); [z.write(f,os.path.basename(f)) for f in sys.argv[2:]]; z.close()' \
"$zip_path" "$src/$app.${{ matrix.exe_ext }}" "$src/data.kres" "$zip_path" "${files[@]}"
done done
ls -la dist/ ls -la dist/
+67 -39
View File
@@ -31,7 +31,7 @@ Rendering is **Skia everywhere** behind one `RenderBackend` — Metal / OpenGL
- **Windows (mingwX64)** links the bitsycore skiko FORK — skiko+Skia compiled - **Windows (mingwX64)** links the bitsycore skiko FORK — skiko+Skia compiled
into `skiko-windows-x64.dll` with a flat extern-C surface, bound from K/N via into `skiko-windows-x64.dll` with a flat extern-C surface, bound from K/N via
an embedded GNU import lib, published to GitHub Packages as an embedded GNU import lib, published to GitHub Packages as
`org.jetbrains.skiko:skiko:0.150.1-mingw.1` (override with `com.bitsycore.skiko:skiko:0.150.1-mingw.1` (override with
`-PskikoMingwVersion`). The runtime DLL is auto-provisioned next to the exe by `-PskikoMingwVersion`). The runtime DLL is auto-provisioned next to the exe by
the bridge plugin (`installWindowsSkiaDll`). See SKIKO-MINGW-FEASIBILITY.md. the bridge plugin (`installWindowsSkiaDll`). See SKIKO-MINGW-FEASIBILITY.md.
@@ -46,8 +46,11 @@ re-implements the layers on top (`androidx.compose.ui.*`, `.foundation.*`,
## Module layout ## Module layout
Library modules mirror upstream Compose Multiplatform's `compose/` tree. Library modules mirror upstream Compose Multiplatform's `compose/` tree.
Only `:window` is the SDL integration layer ("Compose SDL" — SDL3 main loop) The SDL layer is two modules: `:sdl-core` (the NAKED sdl3 cinterop + platform
and lives under `compose/sdl/`. primitives — zero Compose dep, like `skiko`) at `sdl/sdl-core/`, and
`:desktop-native-window` (the SDL3 main-loop shell + app entry point) at
`compose/desktop/native/window/`. `:ui` depends on `:sdl-core` and its renderer
+ SDL↔Compose bridges pick the cinterop from it.
One Gradle module per upstream artifact; the directory mirrors the upstream One Gradle module per upstream artifact; the directory mirrors the upstream
`compose/` path, the gradle path is kept short (redirected via `projectDir`). `compose/` path, the gradle path is kept short (redirected via `projectDir`).
@@ -55,10 +58,18 @@ One Gradle module per upstream artifact; the directory mirrors the upstream
``` ```
compose/ compose/
├── ui/ ├── ui/
│ ├── ui/ → :ui — androidx.compose.ui.* (ui + ui-graphics + ui-text) + │ ├── ui/ → :ui — androidx.compose.ui.* CORE (Modifier, LayoutNode,
│ │ com.compose.sdl.* — the sdl3 cinterop + the Skia renderer │ │ composition, semantics, input, focus) + com.compose.sdl.* —
│ │ pipeline live here. ui-graphics/ui-text can't split off: their │ │ the Skia RenderBackend + GPU bridges + the SDL↔Compose
│ │ Canvas / Paragraph `expect`s are the renderer's `actual`s (same-module). │ │ bridges (events / clipboard / cursors / window). Depends on
│ │ :ui-graphics, :ui-text, :sdl-core. (ui-graphics + ui-text +
│ │ the sdl3 cinterop were split OUT — upstream layout.)
│ ├── ui-graphics/ → :ui-graphics — androidx.compose.ui.graphics.* + the Skia actuals
│ │ (SkiaBackedCanvas/Path/Paint, GraphicsLayer, SkiaImageCache,
│ │ painter/image + resource seams). → skiko; SDL-free.
│ ├── ui-text/ → :ui-text — androidx.compose.ui.text.* + the skiko text engine
│ │ (SkiaParagraph → NativeParagraphOps → SkiaFonts, IconFont,
│ │ NamedFont). → :ui-graphics, skiko; SDL-free.
│ ├── ui-util/ → :ui-util — androidx.compose.ui.util.* (+ Experimental/InternalComposeUiApi) │ ├── ui-util/ → :ui-util — androidx.compose.ui.util.* (+ Experimental/InternalComposeUiApi)
│ ├── ui-geometry/ → :ui-geometry — androidx.compose.ui.geometry.* │ ├── ui-geometry/ → :ui-geometry — androidx.compose.ui.geometry.*
│ ├── ui-unit/ → :ui-unit — androidx.compose.ui.unit.* │ ├── ui-unit/ → :ui-unit — androidx.compose.ui.unit.*
@@ -79,9 +90,15 @@ compose/
│ └── material3/ → :material3 — androidx.compose.material3.* │ └── material3/ → :material3 — androidx.compose.material3.*
├── material/ ├── material/
│ └── material-ripple/ → :material-ripple — androidx.compose.material.ripple.* │ └── material-ripple/ → :material-ripple — androidx.compose.material.ripple.*
└── sdl/ ("Compose SDL" — project modules, not upstream CMP artifacts) └── desktop/native/window/ → :desktop-native-window — nativeComposeApp { Window(...) {} }
└── window/ → :window — nativeComposeApp { Window(...) {} } multi-window multi-window shell + SDL3 main loop; nativeComposeWindow()
shell + SDL3 main loop; nativeComposeWindow() wrapper wrapper (project app-shell, not an upstream CMP artifact).
Published as com.bitsycore.compose:desktop-native-window.
sdl/
└── sdl-core/ → :sdl-core — the NAKED sdl3 cinterop + platform primitives
(zero Compose dep, like skiko); the single `sdl3` cinterop
lives here. :ui depends on it. com.bitsycore.compose.sdl:sdl-core.
utils/ utils/
└── material-symbols/ → :material-symbols — codepoints + all three style objects └── material-symbols/ → :material-symbols — codepoints + all three style objects
@@ -181,7 +198,7 @@ libs/ → gitignored per-host static SDL3 output of
scripts/build-sdl/build-all.py on Windows scripts/build-sdl/build-all.py on Windows
``` ```
Module PATHS stay short (`:ui`, `:foundation`, `:window`, …) — Module PATHS stay short (`:ui`, `:foundation`, `:desktop-native-window`, …) —
`settings.gradle.kts` redirects `projectDir` for each so build files across `settings.gradle.kts` redirects `projectDir` for each so build files across
the repo stay terse. `androidx.collection` is a plain Maven dependency the repo stay terse. `androidx.collection` is a plain Maven dependency
(`androidx.collection:collection`), not a module — same as other simple (`androidx.collection:collection`), not a module — same as other simple
@@ -193,23 +210,27 @@ androidx KMP libs.
:ui ← :animation-core ← :animation ← :foundation ← :material3 ← :demo, :apidemo :ui ← :animation-core ← :animation ← :foundation ← :material3 ← :demo, :apidemo
:ui ← :foundation-layout ←──────────────────────┘ ↑ ↑ :ui ← :foundation-layout ←──────────────────────┘ ↑ ↑
:material-ripple ←────────────┘──────────────┘ :material-ripple ←────────────┘──────────────┘
:foundation, :animation-core ← :window ; :foundation, :material3 ← :material-symbols :foundation, :animation-core ← :desktop-native-window ; :foundation, :material3 ← :material-symbols
``` ```
All edges are `api`, so a consumer of `:foundation` / `:material3` transitively All edges are `api`, so a consumer of `:foundation` / `:material3` transitively
sees the split modules. Full DAG: `:ui-util → collection`; `:ui-geometry → :ui-util`; sees the split modules. Full DAG: `:ui-util → collection`; `:ui-geometry → :ui-util`;
`:ui-unit → :ui-geometry, :ui-util`; `:ui-backhandler → :ui-util, navigationevent`; `:ui-unit → :ui-geometry, :ui-util`; `:ui-backhandler → :ui-util, navigationevent`;
`:ui → :ui-util, :ui-geometry, :ui-unit, :ui-backhandler`; `:animation-core → :ui`; `:sdl-core → sdl3 cinterop (NAKED — no Compose)`;
`:ui-graphics → :ui-geometry, :ui-unit, :ui-util, skiko`;
`:ui-text → :ui-graphics, :ui-unit, :ui-util, skiko`;
`:ui → :ui-graphics, :ui-text, :sdl-core, :ui-util, :ui-geometry, :ui-unit, :ui-backhandler`; `:animation-core → :ui`;
`:foundation-layout → :ui`; `:animation → :animation-core, :foundation-layout`; `:foundation-layout → :ui`; `:animation → :animation-core, :foundation-layout`;
`:foundation → :animation, :foundation-layout, :animation-core, :ui`; `:foundation → :animation, :foundation-layout, :animation-core, :ui`;
`:material-ripple → :foundation, :animation-core`; `:material-ripple → :foundation, :animation-core`;
`:material3 → :foundation, :material-ripple, :animation-core, :foundation-layout`. `:material3 → :foundation, :material-ripple, :animation-core, :foundation-layout`.
`:ui` is the renderer/cinterop hub (the ui-graphics + ui-text `expect`s resolve to `:ui` is the Compose core + the Skia RenderBackend + the SDL↔Compose bridges; it
its Skia renderer `actual`s). The pure lower artifacts (`:ui-util`, sits on `:ui-graphics` / `:ui-text` (the graphics/text primitives + their skiko
`:ui-geometry`, `:ui-unit`, `:ui-backhandler`) are split out below it. Everything `actual`s, SDL-free) and the naked `:sdl-core` (sdl3 cinterop). The pure lower
above `:ui` can only touch renderer / cinterop internals via its public surface. artifacts (`:ui-util`, `:ui-geometry`, `:ui-unit`, `:ui-backhandler`) are below.
`:window` depends on `:ui` + `:foundation` (needs `LazyList`-style scaffolding to Everything above `:ui` touches renderer internals only via its public surface.
`:desktop-native-window` depends on `:ui` + `:foundation` (needs `LazyList`-style scaffolding to
install the popup / scaffold layer at the composition root). install the popup / scaffold layer at the composition root).
## Vendoring philosophy — read this before writing any `androidx.compose.*` code ## Vendoring philosophy — read this before writing any `androidx.compose.*` code
@@ -292,11 +313,12 @@ Two categories of code live in each module:
reconciled by hand. This is fine; do it when the edit is small and reconciled by hand. This is fine; do it when the edit is small and
the file is unlikely to churn upstream. the file is unlikely to churn upstream.
4. **Skiko-specific things go in `:ui/src/skikoRendererMain/`.** When upstream 4. **Skiko-specific things go in a `skikoRendererMain` source set.** When
ships a `.skiko.kt` file that uses Skiko's Canvas / Paragraph / …, the upstream ships a `.skiko.kt` file that uses Skiko's Canvas / Paragraph / …,
`.skiko.kt` variant is fine to vendor into `skikoRendererMain` (the Skia the `.skiko.kt` variant is fine to vendor into `skikoRendererMain` — graphics
drawing pipeline — `SkiaCanvas.kt`, `SkiaTextRenderer.kt`, into `:ui-graphics` (`SkiaBackedCanvas.skiko.kt`, `SkiaImageCache.kt`, …),
`SkiaImageCache.kt`, …). All native targets attach this source set; text into `:ui-text` (`SkiaParagraphEngine.kt`), the render backend into
`:ui` (`SkiaRenderBackend.kt`). All native targets attach this source set;
mingwX64 layers its fork actuals on top under `skikoRendererMingwMain`. mingwX64 layers its fork actuals on top under `skikoRendererMingwMain`.
5. **Multi-OS project code goes through SDL3, not hand-rolled per-target 5. **Multi-OS project code goes through SDL3, not hand-rolled per-target
@@ -315,7 +337,9 @@ call sites don't care.
## Source-set hierarchy (:ui only) ## Source-set hierarchy (:ui only)
`:ui` owns the `sdl3` cinterop + the Skia renderer pipeline. Its source-set tree: `:ui` owns the Skia RenderBackend + GPU bridges. The SAME source-set tree is used
by `:ui-graphics` / `:ui-text` for their skiko `actual`s (only the deps differ);
the `sdl3` cinterop lives in `:sdl-core` (see below). `:ui`'s tree:
``` ```
commonMain commonMain
@@ -339,12 +363,15 @@ fails to come up.
### Cinterop ### Cinterop
`:ui` owns ONE cinterop in `src/nativeInterop/cinterop/`: `sdl3` (SDL_Window / The `sdl3` cinterop lives in the NAKED `:sdl-core` module
SDL_Event / SDL_GetBasePath / clipboard / dialogs / GL+Metal context / (`sdl/sdl-core/src/nativeInterop/cinterop/sdl3.def`: SDL_Window / SDL_Event /
SDL_Renderer-for-CPU-raster). It has no siblings, so there's no SDL_GetBasePath / clipboard / dialogs / GL+Metal context / SDL_Renderer-for-CPU-
`depends = <sibling>` propagation to worry about — cinterop `.def` files list raster). `:ui` depends on `:sdl-core` (`api`), so `:ui`'s renderer + SDL↔Compose
each other under `depends =` and Gradle does NOT auto-add a sibling cinterop's bridges — and `:desktop-native-window` downstream — see `sdl3.*` and inherit SDL3's static-lib +
klib to the `-library` list, but with a single cinterop that gotcha is moot. linker-opt propagation (the `.def` bakes in `staticLibraries = libSDL3.a` + the
per-OS `linkerOpts`, carried through the klib chain to the final exe, so apps
link SDL just by depending on `:ui`/`:desktop-native-window`). `:sdl-core` has NO Compose
dependency, so `:ui → :sdl-core` is cycle-free — the compose way (like `ui → skiko`).
## Density flow (Option B — layout in physical pixels) ## Density flow (Option B — layout in physical pixels)
@@ -379,7 +406,7 @@ Passing raw `px.dp` will double-scale on Retina.
./gradlew :apidemo:runDebugExecutableLinuxX64 ./gradlew :apidemo:runDebugExecutableLinuxX64
# Windows (from Windows — mingw cross-build from macOS/Linux fails at cinterop). # Windows (from Windows — mingw cross-build from macOS/Linux fails at cinterop).
# Links the bitsycore skiko FORK from GitHub Packages (org.jetbrains.skiko:skiko: # Links the bitsycore skiko FORK from GitHub Packages (com.bitsycore.skiko:skiko:
# 0.150.1-mingw.1, override -PskikoMingwVersion); the bridge plugin drops # 0.150.1-mingw.1, override -PskikoMingwVersion); the bridge plugin drops
# skiko-windows-x64.dll next to the exe (installWindowsSkiaDll). # skiko-windows-x64.dll next to the exe (installWindowsSkiaDll).
gradlew.bat :demo:runDebugExecutableMingwX64 gradlew.bat :demo:runDebugExecutableMingwX64
@@ -446,7 +473,7 @@ drift / vendor-clean guardrails are in
## Key files by area — start here when you need to find something ## Key files by area — start here when you need to find something
### Renderer + main loop ### Renderer + main loop
- `compose/sdl/window/src/nativeMain/…/ComposeWindow.kt` — main loop, - `compose/desktop/native/window/src/nativeMain/…/ComposeWindow.kt` — main loop,
recomposer lifecycle, SDL event dispatch, composition-local seeding. recomposer lifecycle, SDL event dispatch, composition-local seeding.
- `compose/ui/ui/src/nativeMain/…/RenderBackend.kt` — the interface. - `compose/ui/ui/src/nativeMain/…/RenderBackend.kt` — the interface.
- `compose/ui/ui/src/nativeMain/…/GpuMode.kt` — sealed driver picker - `compose/ui/ui/src/nativeMain/…/GpuMode.kt` — sealed driver picker
@@ -464,14 +491,15 @@ drift / vendor-clean guardrails are in
alpha bridge). alpha bridge).
- `compose/ui/ui/src/commonMain/…/node/NodeApplier.kt`. - `compose/ui/ui/src/commonMain/…/node/NodeApplier.kt`.
### Text ### Text (all in `:ui-text` now)
- `compose/ui/ui/src/nativeMain/…/ui/text/SdlParagraph.native.kt` — the - `compose/ui/ui-text/src/nativeMain/…/ui/text/SkiaParagraph.native.kt` — the
bridged `Paragraph` implementation (measurement, hit-test, line metrics, `Paragraph` actual (skiko-free; the 30 interface methods over plain data),
span painting). driving the skiko engine through the `NativeParagraphOps` seam.
- `compose/ui/ui/src/nativeMain/…/ui/text/ParagraphFactories.native.kt` — - `compose/ui/ui-text/src/skikoRendererMain/…/renderer/skia/SkiaParagraphEngine.kt`
— `SkiaParagraphOps` (builds/queries the real skiko `skparagraph`) + `SkiaFonts`
(data.kres bytes → skiko Typeface; the port's family/variable-axis model).
- `compose/ui/ui-text/src/nativeMain/…/ui/text/ParagraphFactories.native.kt` —
actuals for the `Paragraph(…)` / `ParagraphIntrinsics(…)` factory family. actuals for the `Paragraph(…)` / `ParagraphIntrinsics(…)` factory family.
- `compose/ui/ui/src/commonMain/…/text/TextMeasurer.kt` — `NativeTextMeasurer`
interface (implemented by `SkiaTextRenderer`).
### Icons ### Icons
- `compose/foundation/foundation/src/nativeMain/…/icons/IconFontIcon.kt` — - `compose/foundation/foundation/src/nativeMain/…/icons/IconFontIcon.kt` —
+3 -3
View File
@@ -72,7 +72,7 @@ saved state behave as they do on Android.
```kotlin ```kotlin
commonMain.dependencies { commonMain.dependencies {
implementation(project(":window")) // window shell + main loop implementation(project(":desktop-native-window")) // window shell + main loop
implementation(project(":material3")) // Material 3 widgets implementation(project(":material3")) // Material 3 widgets
implementation(project(":material-symbols")) // icon-font composables (optional) implementation(project(":material-symbols")) // icon-font composables (optional)
} }
@@ -142,8 +142,8 @@ client certificates.
## Modules ## Modules
One Gradle module per upstream Compose artifact, mirroring the upstream One Gradle module per upstream Compose artifact, mirroring the upstream
`compose/` tree. The renderer and cinterops live in `:ui`; `:window` is the SDL `compose/` tree. The renderer lives in `:ui` and the `sdl3` cinterop in
integration layer. `:material-symbols`, `:components-resources`, and `:sdl-core`; `:desktop-native-window` is the SDL integration layer. `:material-symbols`, `:components-resources`, and
`:navigation3-ui` are project or vendored modules that the official Maven `:navigation3-ui` are project or vendored modules that the official Maven
artifacts do not cover for Kotlin/Native desktop. artifacts do not cover for Kotlin/Native desktop.
+24 -29
View File
@@ -28,12 +28,12 @@ stack, vendored verbatim: `SkiaBackedCanvas`, `SkiaBackedPaint`, `SkiaShader`,
upstream. macOS/Linux link the official Skiko klibs; mingwX64 links the upstream. macOS/Linux link the official Skiko klibs; mingwX64 links the
bitsycore skiko **fork** (`skikoRendererMingwMain`, Route 1a). bitsycore skiko **fork** (`skikoRendererMingwMain`, Route 1a).
The text and image pipeline (`SdlParagraph`, `NativeTextMeasurer`, `IconFont`) The text pipeline is now upstream's own `SkiaParagraph` (skparagraph, vendored
is the port's own engine; glyph rasterization is Skia. GPU path per platform: verbatim); glyph rasterization is Skia. GPU path per platform: Metal (macOS),
Metal (macOS), OpenGL (Linux + Windows), with a CPU-raster `Software` fallback. OpenGL (Linux + Windows), with a CPU-raster `Software` fallback.
The seam is kept as narrow and low as possible. Code flows The seam is kept as narrow and low as possible. Code flows
`Common (upstream) -> shared native engine -> Skia actual / SDL actual`. What we `Common (upstream) -> shared native engine -> Skia actual`. What we
minimize is hand-rolled actual surface, not actual-side line count: a fat minimize is hand-rolled actual surface, not actual-side line count: a fat
vendored-upstream actual (the Skia leg carrying upstream's whole GraphicsLayer vendored-upstream actual (the Skia leg carrying upstream's whole GraphicsLayer
stack) is preferred over a thin hand-written one. stack) is preferred over a thin hand-written one.
@@ -96,26 +96,21 @@ The compositing-strategy contract (`requiresLayer()`, from
upstream does? If not, what real platform constraint forces the difference?" upstream does? If not, what real platform constraint forces the difference?"
Valid answers name a constraint (e.g. no windowing/input toolkit in K/N -> Valid answers name a constraint (e.g. no windowing/input toolkit in K/N ->
SDL3). "It was easier" is not valid. SDL3). "It was easier" is not valid.
- **Text stays the port's engine (B6.3 skipped).** Making Skia-leg text truly - **Text is now upstream's engine (B6.3 done).** Skia-leg text draws through
upstream (`SkiaParagraph`) is a font-subsystem replacement, not a canvas swap: upstream's own `SkiaParagraph` (skparagraph), vendored verbatim — the
two coexisting font-identity models (the port's name-to-bytes `IconFont` + font-subsystem replacement landed: upstream `PlatformFont`/`FontCache`/
no-op resolver vs upstream `PlatformFont`/`FontCache`/`FontCollection`), about `FontCollection` back a `data.kres`-fed font supply, replacing the port's
13 skiko files to re-vendor, about 10 shared actuals to split, a name-to-bytes engine. glyph rasterization stays Skia. This subsumes the P3.1
`data.kres`-to-`FontCache` bridge, no green intermediate, and it discards the metrics work (measurement is now upstream's, so the numbers match by
P3.1 metrics work. ROI is low: the Skia leg already measures text with skiko construction).
`Font` metrics (via `currentTextMeasurer` -> `SkiaTextRenderer`), which is how - **Module split (`:ui-graphics` / `:ui-text`) is done.** The blocker — the
parity reached about 2%. Revisit only if complex-script/bidi fidelity becomes `sdl3` cinterop being a shared substrate that Kotlin/Native can't cleanly
a hard requirement. share across a module boundary — was resolved by extracting a non-upstream
- **Module split (`:ui-graphics` / `:ui-text`) is shelved as infeasible.** Not `:sdl-core` base module that owns the cinterop and api-exposes it. With that
cosmetic churn as originally scoped: the `sdl3` cinterop is a shared substrate base in place, `androidx.compose.ui.graphics.*` / `.text.*` split off into
used by 11 graphics-side files AND 12 platform/windowing/node/resources files `:ui-graphics` / `:ui-text` (matching upstream artifacts), leaving `:ui` as
that stay in `:ui`. Kotlin/Native cannot cleanly share a cinterop klib across a the Compose core + Skia renderer + SDL bridges. `RenderBackend.drawRoot` takes
module boundary, which is exactly why they were merged. A real split needs a `(Canvas) -> Unit`, decoupling the backends from `ComposeRootHost`.
new non-upstream `:ui-cinterop` base module plus cross-module cinterop
api-exposure, which is bigger and more divergent than the "match upstream
artifacts" goal it was meant to serve. The one keeper from the attempt:
`RenderBackend.drawRoot` now takes `(Canvas) -> Unit`, decoupling the backends
from `ComposeRootHost` (a genuine improvement, retained).
- **Real Skia on Windows K/N shipped (Route 1a).** mingwX64 links the bitsycore - **Real Skia on Windows K/N shipped (Route 1a).** mingwX64 links the bitsycore
skiko fork against `skiko-windows-x64.dll` (with an embedded GNU import lib), skiko fork against `skiko-windows-x64.dll` (with an embedded GNU import lib),
published to GitHub Packages and auto-provisioned by the bridge plugin. This published to GitHub Packages and auto-provisioned by the bridge plugin. This
@@ -131,12 +126,12 @@ The compositing-strategy contract (`requiresLayer()`, from
| B2: Skia leg on upstream GraphicsLayer/GraphicsContext | Done | | B2: Skia leg on upstream GraphicsLayer/GraphicsContext | Done |
| B6.1: Skia leg on upstream `SkiaBackedCanvas` + paint/shader | Done | | B6.1: Skia leg on upstream `SkiaBackedCanvas` + paint/shader | Done |
| B6.2: upstream `GraphicsLayer` + delete transient port cluster | Done | | B6.2: upstream `GraphicsLayer` + delete transient port cluster | Done |
| B6.3: upstream text (`SkiaParagraph`) on the Skia leg | Skipped (decision) | | B6.3: upstream text (`SkiaParagraph`) on the Skia leg | Done |
| B5: engine-convergence deltas audit | Done (clean wins spent by B6) | | B5: engine-convergence deltas audit | Done (clean wins spent by B6) |
| P2.2: composition memory leak | Fixed + soak-gated | | P2.2: composition memory leak | Fixed + soak-gated |
| P2.3: outsets / blur / renderEffect | Done via upstream `SkiaGraphicsLayer` | | P2.3: outsets / blur / renderEffect | Done via upstream `SkiaGraphicsLayer` |
| P3.1: text metrics parity (17% median -> 2%) | Done | | P3.1: text metrics parity (17% median -> 2%) | Done |
| Module split | Shelved (infeasible as specified) | | Module split (`:ui-graphics` / `:ui-text` via `:sdl-core`) | Done |
| Track A: real Skia on Windows (Route 1a) | Done | | Track A: real Skia on Windows (Route 1a) | Done |
## 6. Remaining and future work ## 6. Remaining and future work
@@ -203,7 +198,7 @@ remembering.
is not re-recording, not redrawing less. is not re-recording, not redrawing less.
- **A custom `cacheKey` API.** Superseded by the real per-node display list. - **A custom `cacheKey` API.** Superseded by the real per-node display list.
- **Vendoring `RootNodeOwner` / the `ComposeScene` stack.** Coupled to skiko's - **Vendoring `RootNodeOwner` / the `ComposeScene` stack.** Coupled to skiko's
`SkiaLayer` and windowing; it fights the `:window` SDL loop. The port borrows `SkiaLayer` and windowing; it fights the `:desktop-native-window` SDL loop. The port borrows
only the layer engine. only the layer engine.
## 9. Key files ## 9. Key files
@@ -215,5 +210,5 @@ remembering.
hit-test, event dispatch, snapshot observer sweep. hit-test, event dispatch, snapshot observer sweep.
- `compose/ui/ui/src/commonMain/.../node/impl/ComposeOwner.kt`: the project - `compose/ui/ui/src/commonMain/.../node/impl/ComposeOwner.kt`: the project
`Owner` + `GraphicsLayerOwnerLayer` bridge. `Owner` + `GraphicsLayerOwnerLayer` bridge.
- `compose/ui/ui/src/nativeMain/.../ui/text/SdlParagraph.native.kt`: the bridged - `compose/ui/ui-text/src/nativeMain/.../ui/text/SkiaParagraph.native.kt`: the
`Paragraph` (measurement, hit-test, line metrics, span painting). upstream `Paragraph` actual (measurement, hit-test, line metrics, span painting).
+5
View File
@@ -1,5 +1,10 @@
# Skiko on mingwX64 — Feasibility & Effort Assessment # Skiko on mingwX64 — Feasibility & Effort Assessment
> **STATUS: SHIPPED (Route 1a).** The real Skia leg now runs on mingwX64 via the
> bitsycore skiko fork + `skiko-windows-x64.dll`. This document is retained as
> **historical design context** — the feasibility findings and route trade-offs
> that led to the shipped implementation.
Investigation of the effort to run the real Skia leg (`org.jetbrains.skiko`) Investigation of the effort to run the real Skia leg (`org.jetbrains.skiko`)
on the Kotlin/Native **mingwX64** target, under the relaxed constraint that a on the Kotlin/Native **mingwX64** target, under the relaxed constraint that a
**DLL is acceptable** (the static / no-DLL invariant may be dropped). Companion **DLL is acceptable** (the static / no-DLL invariant may be dropped). Companion
+2 -2
View File
@@ -94,7 +94,7 @@ calendar/clock/number prefs). These require a bundled CLDR subset or a K/N i18n
- `:62` `getDateInputFormat()` hardcoded `yyyy-MM-dd` / `'-'`. **Nice-to-have.** - `:62` `getDateInputFormat()` hardcoded `yyyy-MM-dd` / `'-'`. **Nice-to-have.**
- `:65` `is24HourFormat()` hardcoded `true`. **Cosmetic.** - `:65` `is24HourFormat()` hardcoded `true`. **Cosmetic.**
- `compose/ui/ui/src/nativeMain/.../text/platform/NativeStringDelegate.native.kt:17` · `toUpperCase`/`toLowerCase` use locale-independent stdlib casing; the `locale` param is ignored (wrong for Turkish dotted/dotless i, etc.). **Cosmetic.** - `compose/ui/ui/src/nativeMain/.../text/platform/NativeStringDelegate.native.kt:17` · `toUpperCase`/`toLowerCase` use locale-independent stdlib casing; the `locale` param is ignored (wrong for Turkish dotted/dotless i, etc.). **Cosmetic.**
- `compose/ui/ui/src/nativeMain/.../text/intl/Locale.native.kt` · `Locale.isRtl()` not implemented; the pipeline is LTR-only (`SdlParagraph.native.kt` `getBidiRunDirection` always returns `Ltr`; owners/DrawScopes default `LayoutDirection.Ltr`). No RTL shaping. **Nice-to-have.** - `compose/ui/ui/src/nativeMain/.../text/intl/Locale.native.kt` · `Locale.isRtl()` not implemented; the pipeline is LTR-only (`SkiaParagraph.native.kt` hardcodes `textDirection = Ltr`, so `getParagraphDirection` always returns `Ltr`; owners/DrawScopes default `LayoutDirection.Ltr`). No RTL shaping. **Nice-to-have.**
- No `NumberFormat` / currency / decimal-grouping actual exists; numbers render via `toString()` with `.` decimal and no grouping regardless of locale. **Cosmetic.** - No `NumberFormat` / currency / decimal-grouping actual exists; numbers render via `toString()` with `.` decimal and no grouping regardless of locale. **Cosmetic.**
## D. Font resolution ## D. Font resolution
@@ -112,7 +112,7 @@ so the standard CMP way to bundle a font renders correctly.
## E. Text rendering details ## E. Text rendering details
- `compose/ui/ui/src/nativeMain/.../text/SdlParagraph.native.kt:376` · `drawNativeText` accepts and ignores text `Shadow`, stroke `DrawStyle`, and non-`SrcOver` blend, so those never render on text. **Cosmetic.** - `compose/ui/ui-text/src/nativeMain/.../text/SkiaParagraph.native.kt` · text `Shadow` + `TextDecoration` now render (the `paint(...)` overloads forward them to `ops.rebuildAndPaint`), but stroke `DrawStyle` and non-`SrcOver` `blendMode` are still accepted and ignored, so those never render on text. **Cosmetic.**
- `compose/foundation/.../text/StringHelpers.native.kt:31` and `compose/ui/ui/src/nativeMain/.../text/CharHelpers.native.kt:14` · `findPrecedingBreak`/`findFollowingBreak` (and `offsetByCodePoints`) do a codepoint/surrogate walk only, with no ICU grapheme clusters, so caret movement and backspace split combining marks and emoji ZWJ sequences. **Nice-to-have.** - `compose/foundation/.../text/StringHelpers.native.kt:31` and `compose/ui/ui/src/nativeMain/.../text/CharHelpers.native.kt:14` · `findPrecedingBreak`/`findFollowingBreak` (and `offsetByCodePoints`) do a codepoint/surrogate walk only, with no ICU grapheme clusters, so caret movement and backspace split combining marks and emoji ZWJ sequences. **Nice-to-have.**
## F. Drag and drop ## F. Drag and drop
+15 -6
View File
@@ -136,7 +136,7 @@ gradlew.bat :apidemo:runDebugExecutableMingwX64
``` ```
mingwX64 renders through Skia via the **bitsycore skiko fork**, consumed from mingwX64 renders through Skia via the **bitsycore skiko fork**, consumed from
GitHub Packages as `org.jetbrains.skiko:skiko:0.150.1-mingw.1` (macOS/Linux use GitHub Packages as `com.bitsycore.skiko:skiko:0.150.1-mingw.1` (macOS/Linux use
official Skiko). The runtime `skiko-windows-x64.dll` is auto-provisioned next official Skiko). The runtime `skiko-windows-x64.dll` is auto-provisioned next
to the executable by the bridge plugin — no manual copy. The fork itself is to the executable by the bridge plugin — no manual copy. The fork itself is
published by a separate GitHub Actions workflow in the fork repo, out of band published by a separate GitHub Actions workflow in the fork repo, out of band
@@ -158,10 +158,10 @@ single file to edit; know which axis you are changing.
| Version | Where | Notes | | Version | Where | Notes |
|---------|-------|-------| |---------|-------|-------|
| Project release version | The git tag `vX.Y.Z`. `PUBLISH_VERSION` (from the tag) feeds `vPublishVersion` in `build.gradle.kts`, which strips the leading `v`. Group is `com.bitsycore.compose.sdl`. | Set by the tag, not edited by hand. A non-publish build is `0.0.0-SNAPSHOT`. | | Project release version | The git tag `vX.Y.Z`. `PUBLISH_VERSION` (from the tag) feeds `vPublishVersion` in `build.gradle.kts`, which strips the leading `v`. Groups mirror upstream per area (`com.bitsycore.compose.<area>:<module>`, e.g. `com.bitsycore.compose.ui:ui`); project-only modules use `com.bitsycore.compose.sdl` and `:desktop-native-window` is `com.bitsycore.compose` — see `groupFor()` in the root build. | Set by the tag, not edited by hand. A non-publish build is `0.0.0-SNAPSHOT`. |
| Vendored Compose (native side) | `COMPOSE_CORE_REF` and `COMPOSE_REF` in `scripts/compose-fork/compose.properties`, plus `compose` in `gradle/libs.versions.toml`. | Pin to a durable tag (not a `+dev` commit upstream may GC). Re-sync after changing. | | Vendored Compose (native side) | `COMPOSE_CORE_REF` and `COMPOSE_REF` in `scripts/compose-fork/compose.properties`, plus `compose` in `gradle/libs.versions.toml`. | Pin to a durable tag (not a `+dev` commit upstream may GC). Re-sync after changing. |
| JVM parity forcing | `vComposeJvmVersion` in `demo`, `apidemo`, and `material-symbols` `build.gradle.kts`. | Must be a version PUBLISHED to Maven Central. It may lag the vendored native ref (a documented skew) until the matching version is published. | | JVM parity forcing | `vComposeJvmVersion` in `demo`, `apidemo`, and `material-symbols` `build.gradle.kts`. | Must be a version PUBLISHED to Maven Central. It may lag the vendored native ref (a documented skew) until the matching version is published. |
| Skiko | `skiko` in `gradle/libs.versions.toml`. | macOS/Linux use official Skiko; mingwX64 uses the bitsycore fork (`0.150.1-mingw.1` from GitHub Packages), published out of band by the fork repo's own workflow. Must expose the `org.jetbrains.skiko.node` `RenderNode` / `GraphicsContext` API the vendored compose-core uses. Verify with a throwaway `skikoRendererMain` compile if unsure. | | Skiko | `skiko` in `gradle/libs.versions.toml`. | macOS/Linux use official Skiko (`org.jetbrains.skiko`); mingwX64 uses the bitsycore fork (`com.bitsycore.skiko:skiko:0.150.1-mingw.1` from GitHub Packages), published out of band by the fork repo's own workflow. Must expose the `org.jetbrains.skiko.node` `RenderNode` / `GraphicsContext` API the vendored compose-core uses (the fork keeps upstream's `org.jetbrains.skiko.*` package names; only the Maven coord is rebranded). Verify with a throwaway `skikoRendererMain` compile if unsure. |
| SDL3 | `scripts/build-sdl/build-sdl.properties`. | Rebuild `libs/` with `build-all.py` after any change. | | SDL3 | `scripts/build-sdl/build-sdl.properties`. | Rebuild `libs/` with `build-all.py` after any change. |
| Bridge substituted version | Defaults to the bridge plugin's own published version; consumers override with the `composeDesktopNative.version` Gradle property. | The plugin publishes with the release tag, so a consumer on the matching plugin version resolves the right klibs automatically. | | Bridge substituted version | Defaults to the bridge plugin's own published version; consumers override with the `composeDesktopNative.version` Gradle property. | The plugin publishes with the release tag, so a consumer on the matching plugin version resolves the right klibs automatically. |
@@ -187,16 +187,25 @@ Run this on each upstream bump; it is the flow that keeps the sync tax low.
1. Complete the ref-bump flow above and confirm it is green. For a STABLE 1. Complete the ref-bump flow above and confirm it is green. For a STABLE
release, `vComposeJvmVersion` should match the vendored ref (no skew). release, `vComposeJvmVersion` should match the vendored ref (no skew).
2. On a Windows host, run `gradlew :window:compileCommonMainKotlinMetadata`. 2. On a Windows host, run `gradlew :desktop-native-window:compileCommonMainKotlinMetadata`.
Only Windows compiles the full common-metadata variant table, and the root Only Windows compiles the full common-metadata variant table, and the root
KotlinMultiplatform publications live there; a macOS-only publish leaves the KotlinMultiplatform publications live there; a macOS-only publish leaves the
roots without mingwX64 variants (this bit v0.1.15). roots without mingwX64 variants (this bit v0.1.15).
3. `git tag vX.Y.Z && git push origin vX.Y.Z`. This triggers `.github/workflows/publish.yml`. 3. Refresh the klib API baselines: on a Windows host (JDK 21, matching CI) run
`./gradlew apiDump` and commit any diff. Not a hard gate yet — the API is
pre-stable and `apiCheck` isn't wired — but regenerating each release keeps
the baselines honest so the eventual gate is a no-op. `macosArm64` is inferred
from the linux/mingw ABIs (accurate for the target-independent Compose
surface); `:sdl-core` (cinterop) and `:material-symbols` (generated icon maps)
are excluded via `apiValidation.ignoredProjects`. Best host: Windows — it
builds the mingw slice (the fork's unique surface) for real and only infers
macos; the macos ABI is target-independent for the tracked pure-Kotlin modules.
4. `git tag vX.Y.Z && git push origin vX.Y.Z`. This triggers `.github/workflows/publish.yml`.
What the publish job does, so you can read a failure: What the publish job does, so you can read a failure:
- Each host publishes only its own target's publications to GitHub Packages - Each host publishes only its own target's publications to GitHub Packages
under `com.bitsycore.compose.sdl:*`. Windows additionally publishes the root under their per-area `com.bitsycore.compose.*` coords. Windows additionally publishes the root
KotlinMultiplatform metadata, the `jvm` publication, and the bridge plugin KotlinMultiplatform metadata, the `jvm` publication, and the bridge plugin
(only Windows declares every target). (only Windows declares every target).
- The `MODULES` list in the workflow must stay in sync with the modules in - The `MODULES` list in the workflow must stay in sync with the modules in
+1 -1
View File
@@ -81,7 +81,7 @@ kotlin {
} }
nativeMain { nativeMain {
dependencies { dependencies {
implementation(project(":window")) implementation(project(":desktop-native-window"))
implementation(libs.ktor.client.curl) implementation(libs.ktor.client.curl)
} }
} }
+4 -4
View File
@@ -908,7 +908,7 @@ private fun buildBodyChunks(inText: String, inAnn: AnnotatedString, inLinesPerCh
/** Offsets where each source line starts (line i spans [starts[ i], starts[i+1]-1), /** Offsets where each source line starts (line i spans [starts[ i], starts[i+1]-1),
the -1 dropping the '\n'; the last line runs to the string end). One cheap O(n) the -1 dropping the '\n'; the last line runs to the string end). One cheap O(n)
scan, memoised — replaces the old gutter pre-pass that ran measurer.wrap() on scan, memoised — replaces the old gutter pre-pass that measured wrapping on
every one of N lines on each width change (the other half of the freeze). */ every one of N lines on each width change (the other half of the freeze). */
private fun lineStartOffsets(inText: String): IntArray { private fun lineStartOffsets(inText: String): IntArray {
val vStarts = ArrayList<Int>(64) val vStarts = ArrayList<Int>(64)
@@ -963,10 +963,10 @@ internal fun BodyView(
val vGutterWidth = (vDigits * 7 + 4).dp val vGutterWidth = (vDigits * 7 + 4).dp
// Body wrap width (physical px, from onSizeChanged), reported by the body // Body wrap width (physical px, from onSizeChanged), reported by the body
// Box once it's laid out (0 on the first frame). The gutter numbering // Box once it's laid out (0 on the first frame). The gutter numbering
// depends on it — see vNumbers. NativeTextMeasurer.wrap expects the font // depends on it — see vNumbers. Wrap measurement expects the font
// size + max-width in the SAME unit (both physical px on Retina), so we // size + max-width in the SAME unit (both physical px on Retina), so we
// scale 12.sp through the current density here, matching what SdlParagraph // scale 12.sp through the current density here, matching what the paragraph
// does when it builds the body's real paragraph. // engine does when it builds the body's real paragraph.
var vBodyWidthPx by remember { mutableStateOf(0) } var vBodyWidthPx by remember { mutableStateOf(0) }
val vFontPx = with(LocalDensity.current) { 12.sp.toPx().toInt() } val vFontPx = with(LocalDensity.current) { 12.sp.toPx().toInt() }
// Horizontal scroll for no-wrap mode (read-only body only); dormant when wrapping. // Horizontal scroll for no-wrap mode (read-only body only); dormant when wrapping.
@@ -16,7 +16,13 @@ import com.compose.sdl.res.painterResource
import com.compose.sdl.revealInFileManager import com.compose.sdl.revealInFileManager
import com.compose.sdl.showOpenFileDialog import com.compose.sdl.showOpenFileDialog
import com.compose.sdl.showSaveFileDialog import com.compose.sdl.showSaveFileDialog
import com.compose.sdl.text.currentTextMeasurer import com.compose.sdl.text.namedFontFamily
import androidx.compose.ui.text.Paragraph
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.createFontFamilyResolver
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.sp
import io.ktor.client.* import io.ktor.client.*
import io.ktor.client.engine.curl.* import io.ktor.client.engine.curl.*
import okio.FileSystem import okio.FileSystem
@@ -49,8 +55,31 @@ actual fun removeMemoryImage(inKey: String) = removeMemoryResource(inKey)
actual fun memoryImagePainter(inKey: String, inSvg: Boolean): Painter = actual fun memoryImagePainter(inKey: String, inSvg: Boolean): Painter =
painterResource(inKey, if (inSvg) ResourceKind.Svg else ResourceKind.Raster) painterResource(inKey, if (inSvg) ResourceKind.Svg else ResourceKind.Raster)
actual fun wrappedRowCount(inText: String, inFontPx: Int, inMaxWidthPx: Int, inFamilyName: String?): Int = // Cached resolver for wrappedRowCount — the skiko engine resolves fonts by name
currentTextMeasurer.wrap(inText, inFontPx, inMaxWidthPx, inFamilyName).lines.size // (projectFontName), so this is just the required non-null Paragraph argument.
private val mRowCountFontResolver = createFontFamilyResolver()
actual fun wrappedRowCount(inText: String, inFontPx: Int, inMaxWidthPx: Int, inFamilyName: String?): Int {
if (inText.isEmpty()) return 1
// inFontPx is already physical pixels, so measure at density 1 (fontSize.value
// * density = inFontPx) and wrap at inMaxWidthPx px by building a Paragraph.
// lineCount comes from skiko's paragraph layout.
val vStyle = TextStyle(
fontSize = inFontPx.sp,
fontFamily = inFamilyName?.let { namedFontFamily(it) },
)
return Paragraph(
text = inText,
style = vStyle,
constraints = Constraints(maxWidth = inMaxWidthPx.coerceAtLeast(0)),
density = Density(1f),
fontFamilyResolver = mRowCountFontResolver,
spanStyles = emptyList(),
placeholders = emptyList(),
maxLines = Int.MAX_VALUE,
ellipsis = false,
).lineCount
}
actual var editorTabWidth: Int actual var editorTabWidth: Int
get() = TextLayoutConfig.tabWidth get() = TextLayoutConfig.tabWidth
+47 -10
View File
@@ -12,14 +12,49 @@ plugins {
apiValidation { apiValidation {
@OptIn(ExperimentalBCVApi::class) @OptIn(ExperimentalBCVApi::class)
klib { enabled = true } klib { enabled = true }
ignoredProjects.addAll(listOf("demo", "apidemo")) // demo/apidemo: apps, no published API. sdl-core: naked SDL cinterop — its
// "API" is the generated sdl3.* bindings (per-OS, can't infer macos), not our
// surface. material-symbols: auto-generated icon codepoint maps + its jvm
// dump trips BCV's ASM on newer JDKs (class file major 69). Track the
// hand-authored Compose surface, not generated/binding code.
ignoredProjects.addAll(listOf("demo", "apidemo", "sdl-core", "material-symbols"))
} }
// Version is driven by PUBLISH_VERSION (set from the git tag in the publish // Version is driven by PUBLISH_VERSION (set from the git tag in the publish
// workflow, `v1.2.3` → `1.2.3`). Local dev / demo runs default to SNAPSHOT. // workflow, `v1.2.3` → `1.2.3`). Local dev / demo runs default to SNAPSHOT.
val vPublishVersion = (System.getenv("PUBLISH_VERSION") ?: "0.0.0-SNAPSHOT").removePrefix("v") val vPublishVersion = (System.getenv("PUBLISH_VERSION") ?: "0.0.0-SNAPSHOT").removePrefix("v")
// Published groups mirror the org.jetbrains.compose.<area> originals under the
// com.bitsycore fork name, so each module is the obvious 1:1 fork of its upstream
// coord (e.g. org.jetbrains.compose.ui:ui → com.bitsycore.compose.ui:ui). Modules
// with no upstream area (project-only: :sdl-core, :material-symbols) fall through
// to the default com.bitsycore.compose.sdl group; :desktop-native-window is the
// headline app-shell artifact, published under com.bitsycore.compose.
val kDefaultGroup = "com.bitsycore.compose.sdl"
val kAreaGroups = mapOf(
":ui" to "com.bitsycore.compose.ui",
":ui-graphics" to "com.bitsycore.compose.ui",
":ui-text" to "com.bitsycore.compose.ui",
":ui-unit" to "com.bitsycore.compose.ui",
":ui-geometry" to "com.bitsycore.compose.ui",
":ui-util" to "com.bitsycore.compose.ui",
":ui-backhandler" to "com.bitsycore.compose.ui",
":ui-tooling-preview" to "com.bitsycore.compose.ui",
":foundation" to "com.bitsycore.compose.foundation",
":foundation-layout" to "com.bitsycore.compose.foundation",
":animation" to "com.bitsycore.compose.animation",
":animation-core" to "com.bitsycore.compose.animation",
":animation-graphics" to "com.bitsycore.compose.animation",
":material3" to "com.bitsycore.compose.material3",
":material-ripple" to "com.bitsycore.compose.material",
":components-resources" to "com.bitsycore.compose.components",
":navigation3-ui" to "com.bitsycore.navigation3",
":desktop-native-window" to "com.bitsycore.compose",
)
fun groupFor(path: String): String = kAreaGroups[path] ?: kDefaultGroup
allprojects { allprojects {
group = "com.bitsycore.compose.sdl" group = groupFor(path)
version = vPublishVersion version = vPublishVersion
} }
@@ -37,12 +72,13 @@ allprojects {
val kAppModules = setOf(":demo", ":apidemo") val kAppModules = setOf(":demo", ":apidemo")
val kPublishedLibs = setOf( val kPublishedLibs = setOf(
":ui", ":ui-util", ":ui-geometry", ":ui-unit", ":ui-backhandler", ":sdl-core",
":ui-tooling-preview", ":ui", ":ui-util", ":ui-geometry", ":ui-graphics", ":ui-text",
":ui-unit", ":ui-backhandler", ":ui-tooling-preview",
":animation-core", ":animation", ":animation-graphics", ":animation-core", ":animation", ":animation-graphics",
":foundation", ":foundation-layout", ":foundation", ":foundation-layout",
":material3", ":material-ripple", ":material3", ":material-ripple",
":window", ":material-symbols", ":desktop-native-window", ":material-symbols",
":navigation3-ui", ":components-resources", ":navigation3-ui", ":components-resources",
) )
@@ -76,7 +112,7 @@ subprojects {
kPublishedLibs.forEach { modulePath -> kPublishedLibs.forEach { modulePath ->
val vArtifactId = modulePath.removePrefix(":") val vArtifactId = modulePath.removePrefix(":")
substitute(project(modulePath)) substitute(project(modulePath))
.using(module("com.bitsycore.compose.sdl:$vArtifactId:$kConsumeVersion")) .using(module("${groupFor(modulePath)}:$vArtifactId:$kConsumeVersion"))
.because("-PuseGithubPackages=true") .because("-PuseGithubPackages=true")
} }
} }
@@ -135,10 +171,11 @@ allprojects {
if (vNativeTargetTokens.any { name.contains(it, ignoreCase = true) }) { if (vNativeTargetTokens.any { name.contains(it, ignoreCase = true) }) {
resolutionStrategy.dependencySubstitution { resolutionStrategy.dependencySubstitution {
substitute(module("org.jetbrains.compose.ui:ui")).using(project(":ui")) substitute(module("org.jetbrains.compose.ui:ui")).using(project(":ui"))
// ui's split artifacts: ui-graphics + ui-text are merged INTO // ui-graphics / ui-text are their own modules (split out of :ui,
// :ui in the port; ui-unit / ui-geometry have their own modules. // upstream layout). Declare each DIRECTLY so the app commonMain sees
substitute(module("org.jetbrains.compose.ui:ui-graphics")).using(project(":ui")) // them under the granular-metadata visibility rule.
substitute(module("org.jetbrains.compose.ui:ui-text")).using(project(":ui")) substitute(module("org.jetbrains.compose.ui:ui-graphics")).using(project(":ui-graphics"))
substitute(module("org.jetbrains.compose.ui:ui-text")).using(project(":ui-text"))
substitute(module("org.jetbrains.compose.ui:ui-unit")).using(project(":ui-unit")) substitute(module("org.jetbrains.compose.ui:ui-unit")).using(project(":ui-unit"))
substitute(module("org.jetbrains.compose.ui:ui-geometry")).using(project(":ui-geometry")) substitute(module("org.jetbrains.compose.ui:ui-geometry")).using(project(":ui-geometry"))
substitute(module("org.jetbrains.compose.ui:ui-util")).using(project(":ui-util")) substitute(module("org.jetbrains.compose.ui:ui-util")).using(project(":ui-util"))
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:components-resources> // Library unique name: <com.bitsycore.compose.components:components-resources>
open annotation class org.jetbrains.compose.resources/ExperimentalResourceApi : kotlin/Annotation { // org.jetbrains.compose.resources/ExperimentalResourceApi|null[0] open annotation class org.jetbrains.compose.resources/ExperimentalResourceApi : kotlin/Annotation { // org.jetbrains.compose.resources/ExperimentalResourceApi|null[0]
constructor <init>() // org.jetbrains.compose.resources/ExperimentalResourceApi.<init>|<init>(){}[0] constructor <init>() // org.jetbrains.compose.resources/ExperimentalResourceApi.<init>|<init>(){}[0]
} }
@@ -40,11 +40,11 @@ kotlin {
} }
nativeMain { nativeMain {
kotlin.srcDir("src/vendor/native/kotlin") kotlin.srcDir("src/vendor/native/kotlin")
// The Font / Image resource actuals — pure project code that delegates // src/nativeMain/kotlin also holds the Font / Image resource actuals —
// to :ui's IconFont / NamedFont / decodeEncodedImageBitmap (the Skia // pure project code that delegates to the project font registry
// decoder). Renderer-agnostic and skiko-free, so a single native set // (IconFont / NamedFont) and the :ui-graphics Skia decoder
// covers every target. (Dir name is historical — .sdl.kt.) // (decodeEncodedImageBitmap). Skiko-free, so a single native set covers
kotlin.srcDir("src/sdlRendererMain/kotlin") // every target.
} }
} }
@@ -4,11 +4,10 @@
# mingwX64/linux variants, so the runtime library is vendored and the platform # mingwX64/linux variants, so the runtime library is vendored and the platform
# actuals are project code: # actuals are project code:
# src/nativeMain — ResourceReader (data.kres), getSystemEnvironment (SDL), # src/nativeMain — ResourceReader (data.kres), getSystemEnvironment (SDL),
# pure-Kotlin DomXmlParser (upstream's is Darwin NSXMLParser) # pure-Kotlin DomXmlParser (upstream's is Darwin NSXMLParser),
# src/sdlRendererMain — the Font/Image resource actuals: renderer-agnostic # and the Font/Image resource actuals: renderer-agnostic
# project code (image decode via :ui's Skia decoder, Font # project code (image decode via the :ui-graphics Skia
# via the project font registry). Dir name is historical; # decoder, Font via the project font registry)
# the build attaches it to nativeMain.
# Re-sync: python scripts/compose-fork/sync.py components/resources/library # Re-sync: python scripts/compose-fork/sync.py components/resources/library
SET_REPO=https://github.com/JetBrains/compose-multiplatform@<COMPOSE_REF> SET_REPO=https://github.com/JetBrains/compose-multiplatform@<COMPOSE_REF>
@@ -55,9 +54,9 @@ skikoMain/kotlin/org/jetbrains/compose/resources/ResourceReader.skiko.kt -> src/
# Skia-bound pieces — upstream's skikoMain actuals rely on Compose-Desktop Skia # Skia-bound pieces — upstream's skikoMain actuals rely on Compose-Desktop Skia
# extensions (SystemFont / toComposeImageBitmap / nativeCanvas) this port's :ui # extensions (SystemFont / toComposeImageBitmap / nativeCanvas) this port's :ui
# doesn't expose. The module's own Font/Image actuals (src/sdlRendererMain/kotlin/, # doesn't expose. The module's own Font/Image actuals (src/nativeMain/kotlin/)
# attached to nativeMain) use pure project APIs (IconFont / NamedFont / # use pure project APIs (IconFont / NamedFont / decodeEncodedImageBitmap)
# decodeEncodedImageBitmap) instead, so opt the upstream Skia-bound files out. # instead, so opt the upstream Skia-bound files out.
!skikoMain/kotlin/org/jetbrains/compose/resources/ImageResources.skiko.kt !skikoMain/kotlin/org/jetbrains/compose/resources/ImageResources.skiko.kt
!skikoMain/kotlin/org/jetbrains/compose/resources/FontResources.skiko.kt !skikoMain/kotlin/org/jetbrains/compose/resources/FontResources.skiko.kt
!skikoMain/kotlin/org/jetbrains/compose/resources/SvgPainter.kt !skikoMain/kotlin/org/jetbrains/compose/resources/SvgPainter.kt
@@ -15,16 +15,16 @@ import com.compose.sdl.icons.IconFont
import com.compose.sdl.text.NamedFont import com.compose.sdl.text.NamedFont
// ================== // ==================
// MARK: Font actuals — SDL renderer // MARK: Font actuals — Skia text stack via the project font registry
// ================== // ==================
/** The SDL text stack resolves fonts by FAMILY NAME through the project font /** The Skia text stack resolves fonts by FAMILY NAME through the project font
registry (IconFont.registerIcon — the general byte-font table, not just registry (IconFont.registerIcon — the general byte-font table, not just
icons). A font resource therefore loads its bytes through the resource icons). A font resource therefore loads its bytes through the resource
reader, registers them under a per-resource family name, and returns a reader, registers them under a per-resource family name, and returns a
[NamedFont] — `FontFamily(Font(Res.font.x))` then renders through the [NamedFont] — `FontFamily(Font(Res.font.x))` then renders through the
standard project pipeline. Weight/style are carried on the NamedFont; standard project pipeline. Weight/style are carried on the NamedFont;
variation axes apply at draw time via the renderer's axis support. */ variation axes apply at draw time via Skia's axis support. */
private val emptyFont: Font = NamedFont("res-font:<loading>") private val emptyFont: Font = NamedFont("res-font:<loading>")
@@ -12,21 +12,20 @@ import androidx.compose.ui.unit.Density
import com.compose.sdl.graphics.decodeEncodedImageBitmap import com.compose.sdl.graphics.decodeEncodedImageBitmap
// ================== // ==================
// MARK: Image actuals — SDL renderer // MARK: Image actuals — Skia decode via the :ui-graphics hook
// ================== // ==================
/** Decoding goes through the :ui hook the SDL backend registers at init /** Decoding goes through the :ui-graphics Skia hook the SDL backend registers
(SDL3_image, IMG auto-detect). resourceDensity/targetDensity are ignored: at init (decodeEncodedImageBitmap). resourceDensity/targetDensity are ignored:
under this port's Option-B density flow layout runs in physical pixels and under this port's Option-B density flow layout runs in physical pixels and
drawables ship at a single density, so no decode-time rescale applies. */ drawables ship at a single density, so no decode-time rescale applies. */
internal actual fun ByteArray.toImageBitmap(resourceDensity: Int, targetDensity: Int): ImageBitmap = internal actual fun ByteArray.toImageBitmap(resourceDensity: Int, targetDensity: Int): ImageBitmap =
decodeEncodedImageBitmap(this) decodeEncodedImageBitmap(this)
?: error("Image decode failed — is the render backend initialised before painterResource ran?") ?: error("Image decode failed — is the render backend initialised before painterResource ran?")
/** SVG on SDL: SDL3_image rasterises SVG at its intrinsic size (IMG_LoadSVG), /** SVG: Skia rasterises it at its intrinsic size, so the "element" is just the
so the "element" is just the raw bytes and the painter is the rasterised raw bytes and the painter is the rasterised bitmap. No DOM, no vector scaling —
bitmap. No DOM, no vector scaling — prefer XML vector drawables for prefer XML vector drawables for resolution-independent art. */
resolution-independent art on this renderer. */
internal actual class SvgElement(val bytes: ByteArray) internal actual class SvgElement(val bytes: ByteArray)
internal actual fun ByteArray.toSvgElement(): SvgElement = SvgElement(this) internal actual fun ByteArray.toSvgElement(): SvgElement = SvgElement(this)
@@ -4,46 +4,24 @@ package org.jetbrains.compose.resources
import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.InternalResourceApi
import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.ExperimentalResourceApi
import com.compose.sdl.res.preferredLocaleProvider
import kotlinx.cinterop.alloc import com.compose.sdl.res.systemThemeIsDarkProvider
import kotlinx.cinterop.get
import kotlinx.cinterop.memScoped
import kotlinx.cinterop.pointed
import kotlinx.cinterop.ptr
import kotlinx.cinterop.toKString
import kotlinx.cinterop.IntVar
import kotlinx.cinterop.value
import sdl3.SDL_GetPreferredLocales
import sdl3.SDL_GetSystemTheme
import sdl3.SDL_SystemTheme
import sdl3.SDL_free
// ================== // ==================
// MARK: ResourceEnvironment — SDL actual // MARK: ResourceEnvironment — platform-env-seam actual
// ================== // ==================
/** Non-composable system environment for qualifier resolution (values-fr, /** Non-composable system environment for qualifier resolution (values-fr,
drawable-dark, …): locale from SDL_GetPreferredLocales, theme from drawable-dark, …): locale + theme come from the platform-env seams installed
SDL_GetSystemTheme. Density is reported as 1f — under this port's Option-B by the SDL layer, so :components-resources carries no dependency on the sdl3
density flow layout runs in physical pixels and drawables are bundled at a cinterop. Density is reported as 1f — under this port's Option-B density flow
single density, so the mdpi bucket is always the right one. The COMPOSABLE layout runs in physical pixels and drawables are bundled at a single density,
path (rememberResourceEnvironment) doesn't use this: it reads so the mdpi bucket is always the right one. The COMPOSABLE path
LocalDensity / isSystemInDarkTheme from the composition. */ (rememberResourceEnvironment) doesn't use this: it reads LocalDensity /
@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class) isSystemInDarkTheme from the composition. */
internal actual fun getSystemEnvironment(): ResourceEnvironment { internal actual fun getSystemEnvironment(): ResourceEnvironment {
var vLanguage = "" val (vLanguage, vRegion) = preferredLocaleProvider?.invoke() ?: ("" to "")
var vRegion = "" val vDark = systemThemeIsDarkProvider?.invoke() ?: false
memScoped {
val vCount = alloc<IntVar>()
val vLocales = SDL_GetPreferredLocales(vCount.ptr)
if (vLocales != null && vCount.value > 0) {
val vFirst = vLocales[0]?.pointed
vLanguage = vFirst?.language?.toKString() ?: ""
vRegion = vFirst?.country?.toKString() ?: ""
SDL_free(vLocales)
}
}
val vDark = SDL_GetSystemTheme() == SDL_SystemTheme.SDL_SYSTEM_THEME_DARK
return ResourceEnvironment( return ResourceEnvironment(
language = LanguageQualifier(vLanguage), language = LanguageQualifier(vLanguage),
// SDL locales carry language+country only — no script subtag. // SDL locales carry language+country only — no script subtag.
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:animation-core> // Library unique name: <com.bitsycore.compose.animation:animation-core>
open annotation class androidx.compose.animation.core/ExperimentalAnimationSpecApi : kotlin/Annotation { // androidx.compose.animation.core/ExperimentalAnimationSpecApi|null[0] open annotation class androidx.compose.animation.core/ExperimentalAnimationSpecApi : kotlin/Annotation { // androidx.compose.animation.core/ExperimentalAnimationSpecApi|null[0]
constructor <init>() // androidx.compose.animation.core/ExperimentalAnimationSpecApi.<init>|<init>(){}[0] constructor <init>() // androidx.compose.animation.core/ExperimentalAnimationSpecApi.<init>|<init>(){}[0]
} }
@@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
// :animation-core — androidx.compose.animation.core.* vendored VERBATIM from // :animation-core — androidx.compose.animation.core.* vendored VERBATIM from
// upstream. Renderer-agnostic (spring/tween specs, animatable, transition, // upstream. Renderer-agnostic (spring/tween specs, animatable, transition,
// vector math). Split out of :core so :core stays about renderer+ui glue only. // vector math). Split out of :ui so :ui stays about renderer+ui glue only.
// //
// Provenance = animation-core/compose-fork.txt + scripts/compose-fork/compose.properties. // Provenance = animation-core/compose-fork.txt + scripts/compose-fork/compose.properties.
// Never hand-edit files under animation-core/src/vendor/ — change the manifest and // Never hand-edit files under animation-core/src/vendor/ — change the manifest and
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:animation-graphics> // Library unique name: <com.bitsycore.compose.animation:animation-graphics>
open annotation class androidx.compose.animation.graphics/ExperimentalAnimationGraphicsApi : kotlin/Annotation { // androidx.compose.animation.graphics/ExperimentalAnimationGraphicsApi|null[0] open annotation class androidx.compose.animation.graphics/ExperimentalAnimationGraphicsApi : kotlin/Annotation { // androidx.compose.animation.graphics/ExperimentalAnimationGraphicsApi|null[0]
constructor <init>() // androidx.compose.animation.graphics/ExperimentalAnimationGraphicsApi.<init>|<init>(){}[0] constructor <init>() // androidx.compose.animation.graphics/ExperimentalAnimationGraphicsApi.<init>|<init>(){}[0]
} }
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:animation> // Library unique name: <com.bitsycore.compose.animation:animation>
open annotation class androidx.compose.animation/ExperimentalAnimationApi : kotlin/Annotation { // androidx.compose.animation/ExperimentalAnimationApi|null[0] open annotation class androidx.compose.animation/ExperimentalAnimationApi : kotlin/Annotation { // androidx.compose.animation/ExperimentalAnimationApi|null[0]
constructor <init>() // androidx.compose.animation/ExperimentalAnimationApi.<init>|<init>(){}[0] constructor <init>() // androidx.compose.animation/ExperimentalAnimationApi.<init>|<init>(){}[0]
} }
@@ -0,0 +1,35 @@
// Klib ABI Dump
// Targets: [linuxArm64, linuxX64, macosArm64, mingwX64]
// Rendering settings:
// - Signature version: 2
// - Show manifest properties: true
// - Show declarations: true
// Library unique name: <com.bitsycore.compose:desktop-native-window>
abstract interface com.compose.sdl/ApplicationScope { // com.compose.sdl/ApplicationScope|null[0]
abstract fun exitApplication() // com.compose.sdl/ApplicationScope.exitApplication|exitApplication(){}[0]
}
final class com.compose.sdl/AppWindowIcon { // com.compose.sdl/AppWindowIcon|null[0]
constructor <init>(kotlin.collections/List<kotlin/String>, kotlin.collections/List<kotlin/String> = ...) // com.compose.sdl/AppWindowIcon.<init>|<init>(kotlin.collections.List<kotlin.String>;kotlin.collections.List<kotlin.String>){}[0]
final val dark // com.compose.sdl/AppWindowIcon.dark|{}dark[0]
final fun <get-dark>(): kotlin.collections/List<kotlin/String> // com.compose.sdl/AppWindowIcon.dark.<get-dark>|<get-dark>(){}[0]
final val light // com.compose.sdl/AppWindowIcon.light|{}light[0]
final fun <get-light>(): kotlin.collections/List<kotlin/String> // com.compose.sdl/AppWindowIcon.light.<get-light>|<get-light>(){}[0]
}
final val com.compose.sdl/com_compose_sdl_AppWindowIcon$stableprop // com.compose.sdl/com_compose_sdl_AppWindowIcon$stableprop|#static{}com_compose_sdl_AppWindowIcon$stableprop[0]
final var com.compose.sdl/disableInfiniteAnimations // com.compose.sdl/disableInfiniteAnimations|{}disableInfiniteAnimations[0]
final fun <get-disableInfiniteAnimations>(): kotlin/Boolean // com.compose.sdl/disableInfiniteAnimations.<get-disableInfiniteAnimations>|<get-disableInfiniteAnimations>(){}[0]
final fun <set-disableInfiniteAnimations>(kotlin/Boolean) // com.compose.sdl/disableInfiniteAnimations.<set-disableInfiniteAnimations>|<set-disableInfiniteAnimations>(kotlin.Boolean){}[0]
final var com.compose.sdl/useVirtualFrameTime // com.compose.sdl/useVirtualFrameTime|{}useVirtualFrameTime[0]
final fun <get-useVirtualFrameTime>(): kotlin/Boolean // com.compose.sdl/useVirtualFrameTime.<get-useVirtualFrameTime>|<get-useVirtualFrameTime>(){}[0]
final fun <set-useVirtualFrameTime>(kotlin/Boolean) // com.compose.sdl/useVirtualFrameTime.<set-useVirtualFrameTime>|<set-useVirtualFrameTime>(kotlin.Boolean){}[0]
final fun (com.compose.sdl/ApplicationScope).com.compose.sdl/Window(kotlin/Function0<kotlin/Unit>, kotlin/String?, kotlin/Int, kotlin/Int, com.compose.sdl/GpuMode?, com.compose.sdl/AppWindowIcon?, kotlin/Function2<com.compose.sdl/RenderBackend, kotlin/Int, kotlin/Boolean>?, kotlin/Function3<com.compose.sdl/ComposeWindowScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl/Window|Window@com.compose.sdl.ApplicationScope(kotlin.Function0<kotlin.Unit>;kotlin.String?;kotlin.Int;kotlin.Int;com.compose.sdl.GpuMode?;com.compose.sdl.AppWindowIcon?;kotlin.Function2<com.compose.sdl.RenderBackend,kotlin.Int,kotlin.Boolean>?;kotlin.Function3<com.compose.sdl.ComposeWindowScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun com.compose.sdl/com_compose_sdl_AppWindowIcon$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppWindowIcon$stableprop_getter|com_compose_sdl_AppWindowIcon$stableprop_getter(){}[0]
final fun com.compose.sdl/nativeComposeApp(kotlin/Function3<com.compose.sdl/ApplicationScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // com.compose.sdl/nativeComposeApp|nativeComposeApp(kotlin.Function3<com.compose.sdl.ApplicationScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}[0]
final fun com.compose.sdl/nativeComposeWindow(kotlin/String = ..., kotlin/Int = ..., kotlin/Int = ..., com.compose.sdl/GpuMode = ..., com.compose.sdl/AppWindowIcon? = ..., kotlin/Function2<com.compose.sdl/RenderBackend, kotlin/Int, kotlin/Boolean>? = ..., kotlin/Function3<com.compose.sdl/ComposeWindowScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // com.compose.sdl/nativeComposeWindow|nativeComposeWindow(kotlin.String;kotlin.Int;kotlin.Int;com.compose.sdl.GpuMode;com.compose.sdl.AppWindowIcon?;kotlin.Function2<com.compose.sdl.RenderBackend,kotlin.Int,kotlin.Boolean>?;kotlin.Function3<com.compose.sdl.ComposeWindowScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}[0]
final fun com.compose.sdl/windowHasInvalidations(): kotlin/Boolean // com.compose.sdl/windowHasInvalidations|windowHasInvalidations(){}[0]
@@ -1,8 +1,8 @@
// :window — the module apps depend on. Owns nativeComposeWindow() (main loop, // :desktop-native-window — the module apps depend on. Owns nativeComposeWindow() (main loop,
// recomposer lifecycle, event dispatch, Snapshot apply notifications). // recomposer lifecycle, event dispatch, Snapshot apply notifications).
// Renderer selection happens entirely inside :core via source-set wiring // Renderer selection happens entirely inside :ui via source-set wiring
// (skikoRendererMain vs sdlRendererMain) — this module just calls // (skikoRendererMain — Skia-only) — this module just calls
// `createRenderBackend(...)` and `rendererPreferredGpuMode()` from :core and // `createRenderBackend(...)` and `rendererPreferredGpuMode()` from :ui and
// the right symbol resolves per target. // the right symbol resolves per target.
// Publication artifactId (when set up): compose-desktop-native. // Publication artifactId (when set up): compose-desktop-native.
@@ -23,15 +23,15 @@ kotlin {
applyDefaultHierarchyTemplate() applyDefaultHierarchyTemplate()
// sdl3.* types are api-exposed via :ui's cinterop klib — no separate // sdl3.* types are api-exposed via :ui → :sdl-core's cinterop klib — no
// sdl3 cinterop here. // separate sdl3 cinterop here.
sourceSets { sourceSets {
commonMain.dependencies { commonMain.dependencies {
// api so apps depending on :window also get the compose re-impl, // api so apps depending on :desktop-native-window also get the compose re-impl,
// Res/resources, GpuMode, and the renderer pipeline from :core, plus // Res/resources, GpuMode, and the renderer pipeline from :ui, plus
// the foundation / animation-core / animation modules that were split // the foundation / animation-core / animation modules that were split
// out of :core (upstream Compose layout). // out of :ui (upstream Compose layout).
// Material widgets used to be re-exported from :material here; the // Material widgets used to be re-exported from :material here; the
// module was retired when :apidemo and :demo migrated to :material3. // module was retired when :apidemo and :demo migrated to :material3.
// Apps that want Material 3 widgets pull `implementation(project(":material3"))` // Apps that want Material 3 widgets pull `implementation(project(":material3"))`
@@ -64,7 +64,7 @@ import sdl3.SDL_WaitEventTimeout
routes events per SDL window id. routes events per SDL window id.
Per-window pumping order matters: the render-bridge globals Per-window pumping order matters: the render-bridge globals
(currentTextMeasurer / currentImageLoader / viewport) are per-renderer, so the (currentImageLoader / viewport) are per-renderer, so the
loop installs a window's globals before recomposing / laying out / drawing it. loop installs a window's globals before recomposing / laying out / drawing it.
`nativeComposeWindow(...)` remains as the single-window wrapper (all demo `nativeComposeWindow(...)` remains as the single-window wrapper (all demo
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:foundation-layout> // Library unique name: <com.bitsycore.compose.foundation:foundation-layout>
open annotation class androidx.compose.foundation.layout/ExperimentalFlexBoxApi : kotlin/Annotation { // androidx.compose.foundation.layout/ExperimentalFlexBoxApi|null[0] open annotation class androidx.compose.foundation.layout/ExperimentalFlexBoxApi : kotlin/Annotation { // androidx.compose.foundation.layout/ExperimentalFlexBoxApi|null[0]
constructor <init>() // androidx.compose.foundation.layout/ExperimentalFlexBoxApi.<init>|<init>(){}[0] constructor <init>() // androidx.compose.foundation.layout/ExperimentalFlexBoxApi.<init>|<init>(){}[0]
} }
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:foundation> // Library unique name: <com.bitsycore.compose.foundation:foundation>
open annotation class androidx.compose.foundation.lazy.grid/LazyGridScopeMarker : kotlin/Annotation { // androidx.compose.foundation.lazy.grid/LazyGridScopeMarker|null[0] open annotation class androidx.compose.foundation.lazy.grid/LazyGridScopeMarker : kotlin/Annotation { // androidx.compose.foundation.lazy.grid/LazyGridScopeMarker|null[0]
constructor <init>() // androidx.compose.foundation.lazy.grid/LazyGridScopeMarker.<init>|<init>(){}[0] constructor <init>() // androidx.compose.foundation.lazy.grid/LazyGridScopeMarker.<init>|<init>(){}[0]
} }
@@ -1,8 +1,8 @@
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
// :foundation — androidx.compose.foundation.* AND androidx.compose.animation.* // :foundation — androidx.compose.foundation.* AND androidx.compose.animation.*
// (non-core) vendored VERBATIM from upstream. Sits on :core (which still owns // (non-core) vendored VERBATIM from upstream. Sits on :ui (which still owns
// androidx.compose.ui.*, both renderers, cinterops) + :animation-core. // androidx.compose.ui.*, the Skia renderer, cinterops) + :animation-core.
// //
// Why the two upstream modules (`:animation` and `:foundation`) are combined // Why the two upstream modules (`:animation` and `:foundation`) are combined
// here: upstream splits `foundation-layout` off from `foundation`, then has // here: upstream splits `foundation-layout` off from `foundation`, then has
@@ -20,9 +20,9 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
// Note on DarkTheme: foundation declares `internal expect fun _isSystemInDarkTheme()`, // Note on DarkTheme: foundation declares `internal expect fun _isSystemInDarkTheme()`,
// and its actual lives here as a plain nativeMain kt file (see // and its actual lives here as a plain nativeMain kt file (see
// src/nativeMain/kotlin/androidx/compose/foundation/DarkTheme.native.kt) — a single // src/nativeMain/kotlin/androidx/compose/foundation/DarkTheme.native.kt) — a single
// stub returning false. The upstream skiko/sdl per-renderer actuals were dropped // stub returning false. The upstream skiko per-renderer actuals were dropped
// when :foundation was split from :core: expect/actual must live in the same // when :foundation was split from :ui: expect/actual must live in the same
// module, and duplicating the skikoRenderer/sdlRenderer source-set hierarchy on // module, and duplicating the skikoRenderer source-set hierarchy on
// :foundation just to read `LocalSystemTheme` on the Skia path was more build // :foundation just to read `LocalSystemTheme` on the Skia path was more build
// wiring than is worth it for one function no in-repo app calls. // wiring than is worth it for one function no in-repo app calls.
// //
@@ -2,9 +2,10 @@ package androidx.compose.foundation
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import sdl3.SDL_GetSystemTheme import com.compose.sdl.res.systemThemeIsDarkProvider
import sdl3.SDL_SystemTheme
// System dark-theme flag via the platform-env seam (installed by the SDL layer),
// so :foundation carries no dependency on the sdl3 cinterop.
@Composable @Composable
@ReadOnlyComposable @ReadOnlyComposable
internal actual fun _isSystemInDarkTheme(): Boolean = SDL_GetSystemTheme() == SDL_SystemTheme.SDL_SYSTEM_THEME_DARK internal actual fun _isSystemInDarkTheme(): Boolean = systemThemeIsDarkProvider?.invoke() ?: false
@@ -25,7 +25,7 @@ import androidx.compose.ui.unit.sp
The four Material Symbols variable-font axes (fill / weight / grade / The four Material Symbols variable-font axes (fill / weight / grade /
opticalSize) come in via `fontVariationSettings`; use `MaterialIconAxes(…)` opticalSize) come in via `fontVariationSettings`; use `MaterialIconAxes(…)`
to build the list. Skia honours the axes; SDL3_ttf 3.2 ignores them. */ to build the list. Skia honours the axes. */
@Composable @Composable
fun IconFontIcon( fun IconFontIcon(
codepoint: Int, codepoint: Int,
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:material-ripple> // Library unique name: <com.bitsycore.compose.material:material-ripple>
abstract interface androidx.compose.material.ripple/RippleTheme { // androidx.compose.material.ripple/RippleTheme|null[0] abstract interface androidx.compose.material.ripple/RippleTheme { // androidx.compose.material.ripple/RippleTheme|null[0]
abstract fun defaultColor(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.ui.graphics/Color // androidx.compose.material.ripple/RippleTheme.defaultColor|defaultColor(androidx.compose.runtime.Composer?;kotlin.Int){}[0] abstract fun defaultColor(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.ui.graphics/Color // androidx.compose.material.ripple/RippleTheme.defaultColor|defaultColor(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
abstract fun rippleAlpha(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.material.ripple/RippleAlpha // androidx.compose.material.ripple/RippleTheme.rippleAlpha|rippleAlpha(androidx.compose.runtime.Composer?;kotlin.Int){}[0] abstract fun rippleAlpha(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.material.ripple/RippleAlpha // androidx.compose.material.ripple/RippleTheme.rippleAlpha|rippleAlpha(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:material3> // Library unique name: <com.bitsycore.compose.material3:material3>
open annotation class androidx.compose.material3/ExperimentalMaterial3Api : kotlin/Annotation { // androidx.compose.material3/ExperimentalMaterial3Api|null[0] open annotation class androidx.compose.material3/ExperimentalMaterial3Api : kotlin/Annotation { // androidx.compose.material3/ExperimentalMaterial3Api|null[0]
constructor <init>() // androidx.compose.material3/ExperimentalMaterial3Api.<init>|<init>(){}[0] constructor <init>() // androidx.compose.material3/ExperimentalMaterial3Api.<init>|<init>(){}[0]
} }
+1 -1
View File
@@ -35,7 +35,7 @@ kotlin {
api(project(":animation-core")) api(project(":animation-core"))
api(project(":material-ripple")) api(project(":material-ripple"))
// androidx.collection is used by material3 internals (MutableIntObjectMap, …). // androidx.collection is used by material3 internals (MutableIntObjectMap, …).
// Already on the classpath via :core's runtime; declare here for clarity. // Already on the classpath via :ui's runtime; declare here for clarity.
implementation("androidx.collection:collection:1.5.0") implementation("androidx.collection:collection:1.5.0")
// androidx.graphics.shapes.* — MaterialShapes (RoundedPolygon / // androidx.graphics.shapes.* — MaterialShapes (RoundedPolygon /
// Morph / CornerRounding) that WavyProgress / LoadingIndicator use. // Morph / CornerRounding) that WavyProgress / LoadingIndicator use.
-9
View File
@@ -1,9 +0,0 @@
// Klib ABI Dump
// Targets: [linuxArm64, linuxX64, macosArm64, mingwX64]
// Rendering settings:
// - Signature version: 2
// - Show manifest properties: true
// - Show declarations: true
// Library unique name: <com.bitsycore.compose.native:window>
final fun com.compose.desktop.native/nativeComposeWindow(kotlin/String = ..., kotlin/Int = ..., kotlin/Int = ..., com.compose.desktop.native/GpuMode = ..., kotlin/Function2<com.compose.desktop.native/RenderBackend, kotlin/Int, kotlin/Boolean>? = ..., kotlin/Function3<com.compose.desktop.native/ComposeWindowScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // com.compose.desktop.native/nativeComposeWindow|nativeComposeWindow(kotlin.String;kotlin.Int;kotlin.Int;com.compose.desktop.native.GpuMode;kotlin.Function2<com.compose.desktop.native.RenderBackend,kotlin.Int,kotlin.Boolean>?;kotlin.Function3<com.compose.desktop.native.ComposeWindowScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}[0]
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:ui-backhandler> // Library unique name: <com.bitsycore.compose.ui:ui-backhandler>
final class androidx.compose.ui.backhandler/BackEventCompat { // androidx.compose.ui.backhandler/BackEventCompat|null[0] final class androidx.compose.ui.backhandler/BackEventCompat { // androidx.compose.ui.backhandler/BackEventCompat|null[0]
constructor <init>(kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Int) // androidx.compose.ui.backhandler/BackEventCompat.<init>|<init>(kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Int){}[0] constructor <init>(kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Int) // androidx.compose.ui.backhandler/BackEventCompat.<init>|<init>(kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Int){}[0]
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:ui-geometry> // Library unique name: <com.bitsycore.compose.ui:ui-geometry>
final class androidx.compose.ui.geometry/MutableRect { // androidx.compose.ui.geometry/MutableRect|null[0] final class androidx.compose.ui.geometry/MutableRect { // androidx.compose.ui.geometry/MutableRect|null[0]
constructor <init>(kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float) // androidx.compose.ui.geometry/MutableRect.<init>|<init>(kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float){}[0] constructor <init>(kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float) // androidx.compose.ui.geometry/MutableRect.<init>|<init>(kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float){}[0]
File diff suppressed because it is too large Load Diff
+75
View File
@@ -0,0 +1,75 @@
// :ui-graphics — androidx.compose.ui.graphics.* split out of :ui (upstream layout).
// Canvas / Paint / Path / Brush / Color / ImageBitmap / Shader / GraphicsLayer +
// the Skia actuals (SkiaBackedCanvas, SkiaImageCache, …). SDL-free — image bytes
// come through the composeResourceReader seam, so it depends only on skiko +
// the low ui primitives, NOT on :sdl-core.
plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.kotlin.plugin.compose)
alias(libs.plugins.compose.multiplatform)
}
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
kotlin {
linuxArm64()
linuxX64()
macosArm64()
if (vHostSupportsMingw) mingwX64()
applyDefaultHierarchyTemplate()
sourceSets {
commonMain {
kotlin.srcDir("src/vendor/common/kotlin")
dependencies {
api(project(":ui-geometry"))
api(project(":ui-unit"))
api(project(":ui-util"))
api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}")
implementation(libs.kotlinx.coroutines.core)
// androidx.collection comes transitively via :ui-util (api).
}
}
nativeMain {
kotlin.srcDir("src/vendor/native/kotlin")
}
val skikoRendererMain = create("skikoRendererMain") {
dependsOn(nativeMain.get())
kotlin.srcDir("src/vendor/skikoRenderer/kotlin")
dependencies {
implementation(libs.skiko)
}
}
val skikoRendererMacosMain = create("skikoRendererMacosMain") { dependsOn(skikoRendererMain) }
val skikoRendererLinuxMain = create("skikoRendererLinuxMain") { dependsOn(skikoRendererMain) }
get("macosArm64Main").dependsOn(skikoRendererMacosMain)
get("linuxX64Main").dependsOn(skikoRendererLinuxMain)
get("linuxArm64Main").dependsOn(skikoRendererLinuxMain)
if (vHostSupportsMingw) {
val skikoRendererMingwSharedMain = create("skikoRendererMingwSharedMain") {
dependsOn(nativeMain.get())
kotlin.srcDir("src/skikoRendererMain/kotlin")
kotlin.srcDir("src/vendor/skikoRenderer/kotlin")
dependencies {
implementation("com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse("0.150.1-mingw.1")}")
}
}
val skikoRendererMingwMain = create("skikoRendererMingwMain") { dependsOn(skikoRendererMingwSharedMain) }
get("mingwX64Main").dependsOn(skikoRendererMingwMain)
}
}
compilerOptions {
freeCompilerArgs.addAll(
"-Xcollection-literals",
"-Xexpect-actual-classes",
"-opt-in=kotlinx.cinterop.ExperimentalForeignApi",
"-opt-in=androidx.compose.ui.InternalComposeUiApi",
"-opt-in=androidx.compose.ui.ExperimentalComposeUiApi"
)
}
}
+166
View File
@@ -0,0 +1,166 @@
SET_REPO=https://github.com/JetBrains/compose-multiplatform-core@<COMPOSE_CORE_REF>
SET_FOLDER=compose/ui/ui-graphics/src
commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/androidx/compose/ui/graphics/Bezier.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Bezier.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/BlendMode.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/BlendMode.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Brush.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Brush.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Canvas.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Canvas.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/ClipOp.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/ClipOp.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Color.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Color.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/ColorFilter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/ColorFilter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/ColorMatrix.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/ColorMatrix.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Degrees.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Degrees.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/ExperimentalGraphicsApi.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/ExperimentalGraphicsApi.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/FilterQuality.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/FilterQuality.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Float16.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Float16.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/GraphicsContext.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/GraphicsContext.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/ImageBitmap.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/ImageBitmap.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/InlineClassHelper.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/InlineClassHelper.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Interpolatable.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Interpolatable.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/IntervalTree.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/IntervalTree.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/LayerOutsets.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/LayerOutsets.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Matrix.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Matrix.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Outline.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Outline.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Paint.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Paint.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PaintingStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PaintingStyle.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Path.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Path.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathEffect.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathEffect.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathFillType.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathFillType.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathGeometry.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathGeometry.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathHitTester.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathHitTester.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathIterator.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathIterator.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathMeasure.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathMeasure.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathOperation.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathOperation.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathSegment.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathSegment.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathSvg.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathSvg.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PixelMap.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PixelMap.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PointMode.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PointMode.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/RectangleShape.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/RectangleShape.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/RenderEffect.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/RenderEffect.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Shader.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Shader.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Shadow.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Shadow.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Shape.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Shape.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/StrokeCap.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/StrokeCap.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/StrokeJoin.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/StrokeJoin.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/TileMode.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/TileMode.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/VertexMode.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/VertexMode.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Vertices.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Vertices.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Adaptation.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Adaptation.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/ColorModel.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/ColorModel.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpace.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpace.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpaces.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpaces.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Connector.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Connector.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Illuminant.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Illuminant.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Lab.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Lab.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Oklab.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Oklab.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/RenderIntent.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/RenderIntent.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/TransferParameters.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/TransferParameters.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/WhitePoint.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/WhitePoint.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Xyz.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Xyz.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/CanvasDrawScope.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/CanvasDrawScope.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/ContentDrawScope.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/ContentDrawScope.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawContext.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/DrawContext.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawScope.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/DrawScope.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawScopeMarker.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/DrawScopeMarker.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawTransform.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/DrawTransform.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/EmptyCanvas.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/EmptyCanvas.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/internal/JvmDefaultWithCompatibility.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/internal/JvmDefaultWithCompatibility.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/layer/ChildLayerDependenciesTracker.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/layer/ChildLayerDependenciesTracker.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/layer/CompositingStrategy.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/layer/CompositingStrategy.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayer.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayer.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/painter/BrushPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/painter/BrushPainter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/painter/ColorPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/painter/ColorPainter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/painter/Painter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/painter/Painter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/Blur.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/Blur.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/DropShadowPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/DropShadowPainter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/InnerShadowPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/InnerShadowPainter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/Shadow.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/Shadow.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/ShadowContext.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/ShadowContext.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/ShadowRenderer.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/ShadowRenderer.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/vector/FastFloatParser.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/vector/FastFloatParser.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/vector/PathBuilder.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/vector/PathBuilder.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/vector/PathNode.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/vector/PathNode.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/vector/PathParser.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/vector/PathParser.kt
nonJvmMain/kotlin/androidx/compose/ui/graphics/internal/JvmDefaultWithCompatibility.nonJvm.kt -> src/vendor/native/kotlin/androidx/compose/ui/graphics/internal/JvmDefaultWithCompatibility.native.kt
skikoMain/kotlin/ -> src/vendor/skikoRenderer/kotlin/
# | skikoMain/kotlin/androidx/compose/ui/graphics/BlendMode.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/BlendMode.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/ImageBitmap.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/ImageBitmap.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/Matrices.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/Matrices.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/Rects.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/Rects.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedPaint.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedPaint.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedPath.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedPath.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedPathEffect.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedPathEffect.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedPathMeasure.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedPathMeasure.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedRenderEffect.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedRenderEffect.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaColorFilter.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaColorFilter.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaGraphicsContext.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaGraphicsContext.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaImageAsset.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaImageAsset.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaPathIterator.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaPathIterator.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaShader.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaShader.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaTileMode.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaTileMode.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaVertexMode.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaVertexMode.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/layer/SkiaGraphicsLayer.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/layer/SkiaGraphicsLayer.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/shadow/Blur.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/shadow/Blur.skiko.kt
# B6.1 (2026-07-16): un-refused — skiko leg adopts upstream graphics actuals.
# SkiaBackedCanvas is then MANUAL-VENDORED (moved to src/skikoRendererMain, re-refused
# below) to also implement the port Native* draw contracts. See RENDERER_TASKS.md B6.1.
# B6.2: un-refused — skiko leg adopts upstream GraphicsLayer/GraphicsContext (real
# skiko RenderNode) now the canvas is SkiaBackedCanvas. See RENDERER_TASKS.md B6.2.
!skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt
# B6.1: MANUAL-VENDORED (flattened toBitmap/putBytesInto expect-actuals — see the file).
!skikoMain/kotlin/androidx/compose/ui/graphics/SkiaImageAsset.skiko.kt
# >>> ---- DIAGNOSTIC GAPS ---- <<<<
# androidMain (28)
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidBlendMode.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidBlendMode.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidCanvas.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidCanvas.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidColor.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidColor.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidColorFilter.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidColorFilter.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidColorSpace.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidColorSpace.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidGraphicsContext.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidGraphicsContext.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidImageBitmap.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidImageBitmap.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidMatrixConversions.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidMatrixConversions.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidPaint.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidPaint.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidPath.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidPath.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidPathEffect.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidPathEffect.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidPathIterator.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidPathIterator.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidPathMeasure.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidPathMeasure.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidRenderEffect.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidRenderEffect.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidShader.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidShader.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidTileMode.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidTileMode.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/AndroidVertexMode.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/AndroidVertexMode.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/CanvasUtils.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/CanvasUtils.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/RectHelper.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/RectHelper.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayer.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayer.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayerV23.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayerV23.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayerV29.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayerV29.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsViewLayer.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/layer/GraphicsViewLayer.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/layer/LayerSnapshot.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/layer/LayerSnapshot.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/layer/view/PlaceholderHardwareCanvas.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/layer/view/PlaceholderHardwareCanvas.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/layer/view/ViewLayerContainer.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/layer/view/ViewLayerContainer.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/shadow/AndroidShadowContext.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/shadow/AndroidShadowContext.android.kt
# | androidMain/kotlin/androidx/compose/ui/graphics/shadow/Blur.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/graphics/shadow/Blur.android.kt
# desktopMain (7)
# | desktopMain/kotlin/androidx/compose/ui/graphics/DesktopColorFilter.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/graphics/DesktopColorFilter.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/graphics/DesktopImageAsset.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/graphics/DesktopImageAsset.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/graphics/DesktopImageConverters.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/graphics/DesktopImageConverters.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/graphics/DesktopPath.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/graphics/DesktopPath.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/graphics/DesktopPathEffect.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/graphics/DesktopPathEffect.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/graphics/RenderEffect.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/graphics/RenderEffect.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/graphics/awt/AwtColor.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/graphics/awt/AwtColor.desktop.kt
# jvmAndAndroidMain (1)
# | jvmAndAndroidMain/kotlin/androidx/compose/ui/graphics/internal/JvmDefaultWithCompatibility.jvmAndroidAndroid.kt -> src/vendor/jvmAndAndroid/kotlin/androidx/compose/ui/graphics/internal/JvmDefaultWithCompatibility.jvmAndroidAndroid.kt
# nativeMain (1)
# | nativeMain/kotlin/androidx/compose/ui/graphics/NativeImageAsset.native.kt -> src/vendor/native/kotlin/androidx/compose/ui/graphics/NativeImageAsset.native.kt
# skikoExcludingWebMain (1)
# | skikoExcludingWebMain/kotlin/androidx/compose/ui/graphics/Actuals.skikoExcludingWeb.kt -> src/vendor/skikoExcludingWeb/kotlin/androidx/compose/ui/graphics/Actuals.skikoExcludingWeb.kt
# webMain (2)
# | webMain/kotlin/androidx/compose/ui/graphics/Actuals.web.kt -> src/vendor/web/kotlin/androidx/compose/ui/graphics/Actuals.web.kt
# | webMain/kotlin/androidx/compose/ui/graphics/ImageAsset.web.kt -> src/vendor/web/kotlin/androidx/compose/ui/graphics/ImageAsset.web.kt
# <<< ---- DIAGNOSTIC GAPS ---- >>>>
@@ -0,0 +1,16 @@
package com.compose.sdl.graphics
// ==================
// MARK: NativeFinishableCanvas
// ==================
/**
A renderer canvas that must be flushed once drawing into it is done — some backends
batch geometry and only submit on flush; an offscreen canvas must flush before its
backing texture is read. Implemented by SkiaBackedCanvas (no-op — Skia save/restore
is balanced per call). Lets renderer-agnostic code (e.g. GraphicsLayer.toImageBitmap)
commit an offscreen render without knowing the concrete canvas type.
*/
interface NativeFinishableCanvas {
fun finish()
}
@@ -0,0 +1,29 @@
package com.compose.sdl.graphics
import com.compose.sdl.res.ResourceKind
// ==================
// MARK: NativePainterCanvas bridge
// ==================
/**
Image drawing bridge. Renderer Canvas backends (SkiaBackedCanvas) implement this
to paint a bundled resource by path + kind. [com.compose.sdl.res.ResourcePainter]
(an upstream `Painter` subclass in the res pipeline) casts the current Canvas to
this and calls drawNativePainter from inside its `Painter.onDraw()` — reached via
upstream `Modifier.paint(...)` (PainterModifier), which pre-scales the
destination size per ContentScale. So the painter always draws fill-bounds into
the given rect, and this seam carries no ui-layout (ContentScale) dependency —
keeping :ui-graphics free of :ui.
*/
interface NativePainterCanvas {
fun drawNativePainter(
inResourcePath: String,
inKind: ResourceKind,
inX: Float,
inY: Float,
inWidth: Float,
inHeight: Float,
inAlpha: Float,
)
}
@@ -7,7 +7,7 @@ import androidx.compose.ui.graphics.Outline
// MARK: NativeShadowCanvas (render bridge) // MARK: NativeShadowCanvas (render bridge)
// ================== // ==================
/** Drop-shadow bridge, same shape as NativeTextCanvas / NativePainterCanvas: /** Drop-shadow bridge, same shape as NativePainterCanvas:
the render nodes call it when a layer carries shadowElevation > 0 the render nodes call it when a layer carries shadowElevation > 0
(Modifier.shadow, m3 Surface tonal+shadow elevation). The outline is the (Modifier.shadow, m3 Surface tonal+shadow elevation). The outline is the
layer's resolved shape in LAYER-LOCAL pixels — the canvas is already layer's resolved shape in LAYER-LOCAL pixels — the canvas is already
@@ -15,9 +15,7 @@ import androidx.compose.ui.graphics.Outline
paint BEFORE the layer's clip (it lives outside the bounds). paint BEFORE the layer's clip (it lives outside the bounds).
Implementations: Implementations:
- SkiaBackedCanvas — a real Gaussian blur MaskFilter on the outline. - SkiaBackedCanvas — a real Gaussian blur MaskFilter on the outline. */
- Sdl3Canvas — cached shadow tiles (Sdl3ShadowCache) blitted via 9-slice
(the SDL 2D renderer has no shader/blur primitive). */
interface NativeShadowCanvas { interface NativeShadowCanvas {
fun drawDropShadow( fun drawDropShadow(
inOutline: Outline, inOutline: Outline,
@@ -11,10 +11,10 @@ import androidx.compose.ui.geometry.RoundRect
a rounded-rect / circle OUTLINE (not just its bounding box). a rounded-rect / circle OUTLINE (not just its bounding box).
The Skia backend does NOT implement this: Skia's `Canvas.clipPath` already The Skia backend does NOT implement this: Skia's `Canvas.clipPath` already
clips to a rounded path natively. The SDL3 backend has no path-clip primitive clips to a rounded path natively. This side-channel exists for any backend
(only a rectangular render clip), so `Sdl3Canvas` implements this by rendering that has no path-clip primitive (only a rectangular render clip) and must
the clipped subtree into an offscreen target and masking it to the rounded shape emulate it by rendering the clipped subtree into an offscreen target and
(lazily — see the pending-clip machinery there). masking it to the rounded shape.
The render nodes check `canvas is NativeShapeClipCanvas` when a layer has an The render nodes check `canvas is NativeShapeClipCanvas` when a layer has an
`Outline.Rounded` clip and route here; otherwise they fall back to `clipPath`. The pushed clip is scoped to the enclosing `Canvas.save()` / `Outline.Rounded` clip and route here; otherwise they fall back to `clipPath`. The pushed clip is scoped to the enclosing `Canvas.save()` /
@@ -0,0 +1,26 @@
package com.compose.sdl.res
// ==================
// MARK: Platform-environment seams
// ==================
/**
* System-environment seams the platform layer (the SDL module) installs at
* startup, so `:foundation` (`isSystemInDarkTheme`) and `:components-resources`
* (locale / theme resource qualifiers) can read them WITHOUT a dependency on the
* sdl3 cinterop — the cinterop lives in the SDL platform module, but these
* consumers sit below it. null until installed → callers fall back to the light
* theme / empty locale (the sensible headless default).
*/
/** True when the OS is in dark mode. Installed from SDL_GetSystemTheme. */
var systemThemeIsDarkProvider: (() -> Boolean)? = null
/** The OS preferred locale as (language, region) — e.g. ("fr", "FR"); either may
be empty. Installed from SDL_GetPreferredLocales. */
var preferredLocaleProvider: (() -> Pair<String, String>)? = null
/** OS preferred-locale BCP47 tags (language[-REGION]), most-preferred first —
backs androidx.compose.ui.text.intl Locale.current / LocaleList.current (in
:ui-text). Installed from SDL_GetPreferredLocales. */
var preferredLocaleTagsProvider: (() -> List<String>)? = null
@@ -34,8 +34,8 @@ fun resourceKindForPath(path: String): ResourceKind {
// ================== // ==================
/** Shared bridge the commonMain layout pass uses to size images and read raw /** Shared bridge the commonMain layout pass uses to size images and read raw
bytes. The active RenderBackend installs an implementation at startup bytes. The active RenderBackend installs an implementation at startup.
(parallel to currentTextMeasurer). Actual drawing is done by the renderer Actual drawing is done by the renderer
directly off the LayoutNode painter leaf, reusing the backend's decode directly off the LayoutNode painter leaf, reusing the backend's decode
cache — so a decoded texture is created once and shared by measure + draw. */ cache — so a decoded texture is created once and shared by measure + draw. */
interface ImageLoader { interface ImageLoader {
@@ -56,6 +56,13 @@ private val kFallbackImageLoader = object : ImageLoader {
/** Installed by ComposeWindow from renderBackend.imageLoader. */ /** Installed by ComposeWindow from renderBackend.imageLoader. */
var currentImageLoader: ImageLoader = kFallbackImageLoader var currentImageLoader: ImageLoader = kFallbackImageLoader
/** Raw resource-bytes reader (reads an entry from the bundled data.kres). The
platform layer installs the impl (SDL's ResourceIO via SDL_GetBasePath); the
Skia font + image actuals read through this instead of the SDL loader directly,
so ui-graphics / ui-text carry no dependency on the sdl3 cinterop. null until
installed → callers treat that as "resource unavailable". */
var composeResourceReader: ((String) -> ByteArray?)? = null
// ================== // ==================
// MARK: painterResource // MARK: painterResource
// ================== // ==================
@@ -23,7 +23,7 @@ import com.compose.sdl.graphics.NativePainterCanvas
the renderer, so this reduced type carries just the resource pointer. the renderer, so this reduced type carries just the resource pointer.
[onDraw] casts the current Canvas to [NativePainterCanvas] (implemented by [onDraw] casts the current Canvas to [NativePainterCanvas] (implemented by
Sdl3Canvas / SkiaCanvas) and delegates paint to the renderer's image cache. SkiaBackedCanvas) and delegates paint to the renderer's image cache.
If the Canvas doesn't implement NativePainterCanvas (offscreen layer capture If the Canvas doesn't implement NativePainterCanvas (offscreen layer capture
for graphics-layer effects) the paint is skipped. for graphics-layer effects) the paint is skipped.
*/ */
@@ -45,8 +45,7 @@ class ResourcePainter internal constructor(
// translate + scaledSize, so we paint the resource FillBounds into the // translate + scaledSize, so we paint the resource FillBounds into the
// full DrawScope size. Alpha is threaded via applyAlpha. // full DrawScope size. Alpha is threaded via applyAlpha.
(vCanvas as? NativePainterCanvas)?.drawNativePainter( (vCanvas as? NativePainterCanvas)?.drawNativePainter(
resourcePath, kind, 0f, 0f, size.width, size.height, resourcePath, kind, 0f, 0f, size.width, size.height, fAlpha,
androidx.compose.ui.layout.ContentScale.FillBounds, fAlpha,
) )
} }
} }
@@ -11,4 +11,4 @@ import androidx.compose.ui.graphics.GraphicsContext
(the createRenderBackend trick). SDL → the project ProjectGraphicsContext (record/ (the createRenderBackend trick). SDL → the project ProjectGraphicsContext (record/
replay via the SDL NativeRenderNode); Skia → upstream's SkiaGraphicsContext (owns a replay via the SDL NativeRenderNode); Skia → upstream's SkiaGraphicsContext (owns a
skiko RenderNodeContext). See RENDERER.md §4 (B2). */ skiko RenderNodeContext). See RENDERER.md §4 (B2). */
internal expect fun createGraphicsContext(): GraphicsContext expect fun createGraphicsContext(): GraphicsContext
@@ -8,10 +8,9 @@ import androidx.compose.ui.graphics.ImageBitmap
/** Decodes an ENCODED image (png / jpg / webp / bmp / gif / svg bytes) into a /** Decodes an ENCODED image (png / jpg / webp / bmp / gif / svg bytes) into a
drawable [ImageBitmap]. The active renderer registers its implementation at drawable [ImageBitmap]. The active renderer registers its implementation at
backend construction — the SDL backend goes through SDL3_image backend construction — the Skia backend goes through Image.makeFromEncoded /
(Sdl3EncodedImageDecoder), the Skia backend through Image.makeFromEncoded /
SVGDOM (SkiaEncodedImageDecoder). :components-resources' actuals share this SVGDOM (SkiaEncodedImageDecoder). :components-resources' actuals share this
hook under BOTH renderers (its skikoRendererMain reuses the SDL actuals). hook.
Consumed by `ByteArray.toImageBitmap` / `SvgElement.toSvgPainter` so Consumed by `ByteArray.toImageBitmap` / `SvgElement.toSvgPainter` so
painterResource(Res.drawable.x) works without that module reaching into painterResource(Res.drawable.x) works without that module reaching into
@@ -24,7 +23,6 @@ interface EncodedImageDecoder {
resources pipeline on Dispatchers.Default workers. */ resources pipeline on Dispatchers.Default workers. */
@kotlin.concurrent.Volatile @kotlin.concurrent.Volatile
var encodedImageDecoder: EncodedImageDecoder? = null var encodedImageDecoder: EncodedImageDecoder? = null
internal set
/** Decode via the active renderer's registered decoder — null when no renderer /** Decode via the active renderer's registered decoder — null when no renderer
* has initialised yet or the bytes aren't a supported image. */ * has initialised yet or the bytes aren't a supported image. */
@@ -16,7 +16,7 @@ import kotlin.math.abs
// Builds the layer transform (translation / rotation / scale / camera about a // Builds the layer transform (translation / rotation / scale / camera about a
// pivot) into [matrix]. Matches the skiko copy so hit-testing agrees across legs. // pivot) into [matrix]. Matches the skiko copy so hit-testing agrees across legs.
internal fun prepareLayerTransformationMatrix( fun prepareLayerTransformationMatrix(
matrix: Matrix, matrix: Matrix,
pivotX: Float, pivotX: Float,
pivotY: Float, pivotY: Float,
@@ -17,11 +17,11 @@
// DERIVED (copy + edit) from compose-multiplatform-core -- MANUAL VENDOR, NON-IDEMPOTENT. // DERIVED (copy + edit) from compose-multiplatform-core -- MANUAL VENDOR, NON-IDEMPOTENT.
// VENDOR-BASE: compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt @ v1.12.0-beta03+dev4483 // VENDOR-BASE: compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt @ v1.12.0-beta03+dev4483
// ONLY change vs upstream: this class also implements the port draw contracts // ONLY change vs upstream: this class also implements the port draw contracts
// (NativeTextCanvas / NativePainterCanvas / NativeShadowCanvas / NativeFinishableCanvas) so // (NativePainterCanvas / NativeShadowCanvas / NativeFinishableCanvas) so the
// the port text engine (SkiaTextRenderer, P3.1 metrics) + resource-image cache + elevation // resource-image cache + elevation shadows keep working on the Skia renderer,
// shadows keep working on the Skia leg, which now draws through THIS canvas instead of the // which draws through THIS canvas instead of the retired project SkiaCanvas.
// retired project SkiaCanvas. Bridged methods forward to `skiaLeafDrawer` using // Bridged methods forward to `skiaLeafDrawer` using `internalSkiaCanvas`.
// `internalSkiaCanvas`. See RENDERER.md (B6.1, section 4). // See RENDERER.md (B6.1, section 4).
package androidx.compose.ui.graphics package androidx.compose.ui.graphics
@@ -503,7 +503,6 @@ internal class SkiaBackedCanvas(
inY: Float, inY: Float,
inWidth: Float, inWidth: Float,
inHeight: Float, inHeight: Float,
inContentScale: androidx.compose.ui.layout.ContentScale,
inAlpha: Float, inAlpha: Float,
) { ) {
val drawer = skiaLeafDrawer ?: return val drawer = skiaLeafDrawer ?: return
@@ -515,7 +514,6 @@ internal class SkiaBackedCanvas(
inY = inY, inY = inY,
inW = inWidth, inW = inWidth,
inH = inHeight, inH = inHeight,
inScale = inContentScale,
inAlpha = inAlpha, inAlpha = inAlpha,
) )
} }
@@ -10,4 +10,4 @@ import androidx.compose.ui.graphics.SkiaGraphicsContext
/** The Skia leg uses upstream's SkiaGraphicsContext, which owns a skiko /** The Skia leg uses upstream's SkiaGraphicsContext, which owns a skiko
RenderNodeContext and creates upstream GraphicsLayer(skiko.RenderNode) instances. RenderNodeContext and creates upstream GraphicsLayer(skiko.RenderNode) instances.
See RENDERER.md (B6.2, section 4). */ See RENDERER.md (B6.2, section 4). */
internal actual fun createGraphicsContext(): GraphicsContext = SkiaGraphicsContext() actual fun createGraphicsContext(): GraphicsContext = SkiaGraphicsContext()
@@ -18,7 +18,7 @@ import org.jetbrains.skia.Surface
Returns null if anything along the way fails: the Surface may not yet Returns null if anything along the way fails: the Surface may not yet
exist (first frame), the GPU readback may fail, or bitmap.readPixels() exist (first frame), the GPU readback may fail, or bitmap.readPixels()
may not be exposed in this Skiko build. */ may not be exposed in this Skiko build. */
internal fun readBackBgra(inSurface: Surface?, inWidth: Int, inHeight: Int): Triple<Int, Int, ByteArray>? { fun readBackBgra(inSurface: Surface?, inWidth: Int, inHeight: Int): Triple<Int, Int, ByteArray>? {
val vSurface = inSurface ?: return null val vSurface = inSurface ?: return null
if (inWidth <= 0 || inHeight <= 0) return null if (inWidth <= 0 || inHeight <= 0) return null
val vBitmap = Bitmap() val vBitmap = Bitmap()
@@ -1,11 +1,8 @@
package com.compose.sdl.renderer.skia package com.compose.sdl.renderer.skia
import com.compose.sdl.*
import androidx.compose.ui.layout.ContentScale
import com.compose.sdl.res.AndroidVectorToSvg import com.compose.sdl.res.AndroidVectorToSvg
import com.compose.sdl.res.ResourceKind import com.compose.sdl.res.ResourceKind
import androidx.compose.ui.unit.IntSize import com.compose.sdl.res.composeResourceReader
import org.jetbrains.skia.Canvas import org.jetbrains.skia.Canvas
import org.jetbrains.skia.Color import org.jetbrains.skia.Color
import org.jetbrains.skia.Data import org.jetbrains.skia.Data
@@ -14,8 +11,6 @@ import org.jetbrains.skia.Paint
import org.jetbrains.skia.Rect import org.jetbrains.skia.Rect
import org.jetbrains.skia.Surface import org.jetbrains.skia.Surface
import org.jetbrains.skia.svg.SVGDOM import org.jetbrains.skia.svg.SVGDOM
import kotlin.math.max
import kotlin.math.min
// ================== // ==================
// MARK: SkiaImageCache // MARK: SkiaImageCache
@@ -31,7 +26,7 @@ import kotlin.math.min
NOTE: this source set isn't compiled on the mingwX64 host, so it is built NOTE: this source set isn't compiled on the mingwX64 host, so it is built
only on macOS / Linux — keep it to the Skiko APIs already used elsewhere in only on macOS / Linux — keep it to the Skiko APIs already used elsewhere in
this module. */ this module. */
internal class SkiaImageCache { class SkiaImageCache {
// Value is null when a decode failed — cached to avoid retrying each frame. // Value is null when a decode failed — cached to avoid retrying each frame.
private val fCache = HashMap<String, Image?>() private val fCache = HashMap<String, Image?>()
@@ -49,7 +44,7 @@ internal class SkiaImageCache {
} }
private fun decode(inPath: String, inKind: ResourceKind): Image? { private fun decode(inPath: String, inKind: ResourceKind): Image? {
val vBytes = loadComposeResourceBytes(inPath) ?: return null val vBytes = composeResourceReader?.invoke(inPath) ?: return null
return when (inKind) { return when (inKind) {
ResourceKind.Raster -> runCatching { Image.makeFromEncoded(vBytes) }.getOrNull() ResourceKind.Raster -> runCatching { Image.makeFromEncoded(vBytes) }.getOrNull()
ResourceKind.Svg -> rasterizeSvg(vBytes) ResourceKind.Svg -> rasterizeSvg(vBytes)
@@ -73,7 +68,6 @@ internal class SkiaImageCache {
inY: Float, inY: Float,
inW: Float, inW: Float,
inH: Float, inH: Float,
inScale: ContentScale,
inAlpha: Float, inAlpha: Float,
) { ) {
if (inW <= 0f || inH <= 0f) return if (inW <= 0f || inH <= 0f) return
@@ -85,30 +79,9 @@ internal class SkiaImageCache {
val vPaint = Paint() val vPaint = Paint()
vPaint.color = Color.makeARGB((inAlpha * 255f).toInt().coerceIn(0, 255), 255, 255, 255) vPaint.color = Color.makeARGB((inAlpha * 255f).toInt().coerceIn(0, 255), 255, 255, 255)
when (inScale) { // Upstream PainterModifier pre-scales the destination per ContentScale, so
ContentScale.FillBounds -> { // draw fill-bounds into the given rect.
inCanvas.drawImageRect(vImg, Rect.makeWH(vIw, vIh), Rect.makeXYWH(inX, inY, inW, inH), vPaint) inCanvas.drawImageRect(vImg, Rect.makeWH(vIw, vIh), Rect.makeXYWH(inX, inY, inW, inH), vPaint)
}
ContentScale.Crop -> {
val vScale = max(inW / vIw, inH / vIh)
val vSrcW = inW / vScale
val vSrcH = inH / vScale
val vSrc = Rect.makeXYWH((vIw - vSrcW) / 2f, (vIh - vSrcH) / 2f, vSrcW, vSrcH)
inCanvas.drawImageRect(vImg, vSrc, Rect.makeXYWH(inX, inY, inW, inH), vPaint)
}
else -> {
val vScale = when (inScale) {
ContentScale.Fit -> min(inW / vIw, inH / vIh)
ContentScale.Inside -> min(1f, min(inW / vIw, inH / vIh))
else -> 1f // None
}
val vDw = vIw * vScale
val vDh = vIh * vScale
val vDx = inX + (inW - vDw) / 2f
val vDy = inY + (inH - vDh) / 2f
inCanvas.drawImageRect(vImg, Rect.makeWH(vIw, vIh), Rect.makeXYWH(vDx, vDy, vDw, vDh), vPaint)
}
}
vPaint.close() vPaint.close()
} }
@@ -10,8 +10,8 @@ package com.compose.sdl.renderer.skia
`SkiaBackedCanvas`'s `NativePainterCanvas` contract forwards to. Set once by `SkiaBackedCanvas`'s `NativePainterCanvas` contract forwards to. Set once by
`SkiaRenderBackend`; any `SkiaBackedCanvas` (frame, offscreen, or a GraphicsLayer `SkiaRenderBackend`; any `SkiaBackedCanvas` (frame, offscreen, or a GraphicsLayer
recording — B6.2) can then draw images onto its own `internalSkiaCanvas`. */ recording — B6.2) can then draw images onto its own `internalSkiaCanvas`. */
internal var skiaLeafDrawer: SkiaLeafDrawer? = null var skiaLeafDrawer: SkiaLeafDrawer? = null
internal class SkiaLeafDrawer( class SkiaLeafDrawer(
val imageCache: SkiaImageCache, val imageCache: SkiaImageCache,
) )
@@ -9,18 +9,18 @@ import org.jetbrains.skia.Image
// MARK: SkiaEncodedImageDecoder // MARK: SkiaEncodedImageDecoder
// ================== // ==================
/** Encoded-image decode hook impl for the Skia renderer — the counterpart of /** Encoded-image decode hook impl for the Skia renderer, consumed by
Sdl3EncodedImageDecoder, consumed by :components-resources' actuals :components-resources' actuals (painterResource / SVG). Raster formats go
(painterResource / SVG). Raster formats go through Image.makeFromEncoded; through Image.makeFromEncoded; when that fails the bytes are retried as SVG
when that fails the bytes are retried as SVG through the same SVGDOM through the same SVGDOM rasterisation SkiaImageCache uses. Pure CPU raster
rasterisation SkiaImageCache uses. Pure CPU raster (no GrContext), so it is (no GrContext), so it is safe on the resources pipeline's Dispatchers.Default
safe on the resources pipeline's Dispatchers.Default workers. workers.
B6.1: produces an UPSTREAM ImageBitmap (Image.toComposeImageBitmap) — the Skia B6.1: produces an UPSTREAM ImageBitmap (Image.toComposeImageBitmap) — the Skia
leg now uses upstream's SkiaBackedCanvas/SkiaImageAsset, so the offscreen + renderer uses upstream's SkiaBackedCanvas/SkiaImageAsset, so the offscreen +
ImageBitmap-backed paths go through upstream's own actuals (the project ImageBitmap-backed paths go through upstream's own actuals (the project
SkiaImageBitmap / SkiaOffscreenRenderer are retired). */ SkiaImageBitmap / SkiaOffscreenRenderer are retired). */
internal class SkiaEncodedImageDecoder : EncodedImageDecoder { class SkiaEncodedImageDecoder : EncodedImageDecoder {
override fun decode(inBytes: ByteArray): ImageBitmap? { override fun decode(inBytes: ByteArray): ImageBitmap? {
if (inBytes.isEmpty()) return null if (inBytes.isEmpty()) return null
File diff suppressed because it is too large Load Diff
+74
View File
@@ -0,0 +1,74 @@
// :ui-text — androidx.compose.ui.text.* split out of :ui (upstream layout).
// AnnotatedString / TextStyle / Paragraph / FontFamily + the B6.3 skiko text
// engine (SkiaParagraph / SkiaParagraphOps / SkiaFonts, IconFont). SDL-free —
// depends on :ui-graphics (Canvas), skiko, and the low ui primitives.
plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.kotlin.plugin.compose)
alias(libs.plugins.compose.multiplatform)
}
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
kotlin {
linuxArm64()
linuxX64()
macosArm64()
if (vHostSupportsMingw) mingwX64()
applyDefaultHierarchyTemplate()
sourceSets {
commonMain {
kotlin.srcDir("src/vendor/common/kotlin")
dependencies {
api(project(":ui-graphics"))
api(project(":ui-unit"))
api(project(":ui-util"))
api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}")
api("org.jetbrains.compose.runtime:runtime-saveable:${libs.versions.composeRuntime.get()}")
implementation(libs.kotlinx.coroutines.core)
}
}
nativeMain {
kotlin.srcDir("src/vendor/native/kotlin")
}
val skikoRendererMain = create("skikoRendererMain") {
dependsOn(nativeMain.get())
kotlin.srcDir("src/vendor/skikoRenderer/kotlin")
dependencies {
implementation(libs.skiko)
}
}
val skikoRendererMacosMain = create("skikoRendererMacosMain") { dependsOn(skikoRendererMain) }
val skikoRendererLinuxMain = create("skikoRendererLinuxMain") { dependsOn(skikoRendererMain) }
get("macosArm64Main").dependsOn(skikoRendererMacosMain)
get("linuxX64Main").dependsOn(skikoRendererLinuxMain)
get("linuxArm64Main").dependsOn(skikoRendererLinuxMain)
if (vHostSupportsMingw) {
val skikoRendererMingwSharedMain = create("skikoRendererMingwSharedMain") {
dependsOn(nativeMain.get())
kotlin.srcDir("src/skikoRendererMain/kotlin")
kotlin.srcDir("src/vendor/skikoRenderer/kotlin")
dependencies {
implementation("com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse("0.150.1-mingw.1")}")
}
}
val skikoRendererMingwMain = create("skikoRendererMingwMain") { dependsOn(skikoRendererMingwSharedMain) }
get("mingwX64Main").dependsOn(skikoRendererMingwMain)
}
}
compilerOptions {
freeCompilerArgs.addAll(
"-Xcollection-literals",
"-Xexpect-actual-classes",
"-opt-in=kotlinx.cinterop.ExperimentalForeignApi",
"-opt-in=androidx.compose.ui.InternalComposeUiApi",
"-opt-in=androidx.compose.ui.ExperimentalComposeUiApi"
)
}
}
+256
View File
@@ -0,0 +1,256 @@
SET_REPO=https://github.com/JetBrains/compose-multiplatform-core@<COMPOSE_CORE_REF>
SET_FOLDER=compose/ui/ui-text/src
commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/AnnotatedString.kt
# | commonMain/kotlin/androidx/compose/ui/text/AtomicReference.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/AtomicReference.kt
# | commonMain/kotlin/androidx/compose/ui/text/Bullet.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/Bullet.kt
# | commonMain/kotlin/androidx/compose/ui/text/CharHelpers.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/CharHelpers.kt
# | commonMain/kotlin/androidx/compose/ui/text/ExperimentalTextApi.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/ExperimentalTextApi.kt
# | commonMain/kotlin/androidx/compose/ui/text/InternalTextApi.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/InternalTextApi.kt
# | commonMain/kotlin/androidx/compose/ui/text/LinkAnnotation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/LinkAnnotation.kt
# | commonMain/kotlin/androidx/compose/ui/text/LinkInteractionListener.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/LinkInteractionListener.kt
# | commonMain/kotlin/androidx/compose/ui/text/MultiParagraph.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/MultiParagraph.kt
# | commonMain/kotlin/androidx/compose/ui/text/MultiParagraphIntrinsics.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/MultiParagraphIntrinsics.kt
# | commonMain/kotlin/androidx/compose/ui/text/Paragraph.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/Paragraph.kt
# | commonMain/kotlin/androidx/compose/ui/text/ParagraphIntrinsics.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/ParagraphIntrinsics.kt
# | commonMain/kotlin/androidx/compose/ui/text/ParagraphStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/ParagraphStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/Placeholder.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/Placeholder.kt
# | commonMain/kotlin/androidx/compose/ui/text/PlatformTextStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/PlatformTextStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/Savers.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/Savers.kt
# | commonMain/kotlin/androidx/compose/ui/text/SpanStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/SpanStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/String.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/String.kt
# | commonMain/kotlin/androidx/compose/ui/text/StringAnnotation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/StringAnnotation.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextGranularity.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextGranularity.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextInclusionStrategy.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextInclusionStrategy.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextLayoutResult.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextLayoutResult.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextLinkStyles.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextLinkStyles.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextMeasurer.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextPainter.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextRange.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextRange.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/TtsAnnotation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TtsAnnotation.kt
# | commonMain/kotlin/androidx/compose/ui/text/UrlAnnotation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/UrlAnnotation.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsage.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsage.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/Font.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/Font.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontFamily.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontFamily.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontFamilyTypefaceAdapter.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontFamilyTypefaceAdapter.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontLoadingStrategy.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontLoadingStrategy.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontMatcher.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontMatcher.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontSynthesis.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontSynthesis.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontVariation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontVariation.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontWeight.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontWeight.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/Typeface.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/Typeface.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/EditCommand.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/EditCommand.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/EditProcessor.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/EditProcessor.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/EditingBuffer.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/EditingBuffer.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/GapBuffer.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/GapBuffer.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/ImeAction.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/ImeAction.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/ImeOptions.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/ImeOptions.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/InputEventCallback.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/InputEventCallback.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/KeyboardCapitalization.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/KeyboardCapitalization.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/KeyboardType.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/KeyboardType.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/MathUtils.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/MathUtils.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/OffsetMapping.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/OffsetMapping.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/TextFieldValue.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/TextFieldValue.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/TextInputService.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/VisualTransformation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/VisualTransformation.kt
# | commonMain/kotlin/androidx/compose/ui/text/internal/InlineClassHelper.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/internal/InlineClassHelper.kt
# | commonMain/kotlin/androidx/compose/ui/text/internal/JvmDefaultWithCompatibility.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/internal/JvmDefaultWithCompatibility.kt
# | commonMain/kotlin/androidx/compose/ui/text/intl/Locale.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/intl/Locale.kt
# | commonMain/kotlin/androidx/compose/ui/text/intl/LocaleList.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/intl/LocaleList.kt
# | commonMain/kotlin/androidx/compose/ui/text/intl/PlatformLocale.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/intl/PlatformLocale.kt
# | commonMain/kotlin/androidx/compose/ui/text/platform/Dispatcher.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/platform/Dispatcher.kt
# | commonMain/kotlin/androidx/compose/ui/text/platform/PlatformMultiParagraphDraw.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/platform/PlatformMultiParagraphDraw.kt
# | commonMain/kotlin/androidx/compose/ui/text/platform/PlatformString.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/platform/PlatformString.kt
# | commonMain/kotlin/androidx/compose/ui/text/platform/Synchronization.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/platform/Synchronization.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/BaselineShift.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/BaselineShift.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/Hyphens.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/Hyphens.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/LineBreak.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/LineBreak.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/LineHeightStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/LineHeightStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/ResolvedTextDirection.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/ResolvedTextDirection.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextAlign.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextAlign.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextDecoration.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextDecoration.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextDirection.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextDirection.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextForegroundStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextForegroundStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextGeometricTransform.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextGeometricTransform.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextIndent.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextIndent.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextMotion.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextMotion.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextOverflow.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextOverflow.kt
!commonMain/kotlin/androidx/compose/ui/text/platform/Synchronization.kt
nativeMain/kotlin/androidx/compose/ui/text/WeakReference.native.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/WeakReference.native.kt
nativeMain/kotlin/androidx/compose/ui/text/font/FontSynthesis.native.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/font/FontSynthesis.native.kt
nonJvmMain/kotlin/ -> src/vendor/native/kotlin/
# | nonJvmMain/kotlin/androidx/compose/ui/text/AnnotatedString.nonJvm.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/AnnotatedString.nonJvm.kt
# | nonJvmMain/kotlin/androidx/compose/ui/text/AtomicReference.nonJvm.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/AtomicReference.nonJvm.kt
# | nonJvmMain/kotlin/androidx/compose/ui/text/CharHelpers.nonJvm.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/CharHelpers.nonJvm.kt
# | nonJvmMain/kotlin/androidx/compose/ui/text/input/GapBuffer.nonJvmMain.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/input/GapBuffer.nonJvmMain.kt
# | nonJvmMain/kotlin/androidx/compose/ui/text/internal/JvmDefaultWithCompatibility.nonJvmNative.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/internal/JvmDefaultWithCompatibility.nonJvmNative.kt
!nonJvmMain/kotlin/androidx/compose/ui/text/CharHelpers.nonJvm.kt
skikoMain/kotlin/androidx/compose/ui/text/Paragraph.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/Paragraph.native.kt
skikoMain/kotlin/androidx/compose/ui/text/Savers.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/Savers.native.kt
skikoMain/kotlin/androidx/compose/ui/text/TextDecorationLineStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextDecorationLineStyle.kt
skikoMain/kotlin/androidx/compose/ui/text/TextStyle.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/TextStyle.native.kt
skikoMain/kotlin/androidx/compose/ui/text/UnresolvedSymbolsRegistry.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/UnresolvedSymbolsRegistry.native.kt
skikoMain/kotlin/androidx/compose/ui/text/WeakReference.skiko.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/WeakReference.kt
skikoMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.native.kt
skikoMain/kotlin/androidx/compose/ui/text/input/PlatformTextInputService2.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/input/PlatformTextInputService2.kt
skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaMultiParagraphDraw.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/platform/SkiaMultiParagraphDraw.native.kt
skikoMain/kotlin/androidx/compose/ui/text/style/LineBreak.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/style/LineBreak.native.kt
skikoMain/kotlin/androidx/compose/ui/text/style/TextMotion.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/style/TextMotion.native.kt
# >>> ---- DIAGNOSTIC GAPS ---- <<<<
# androidMain (77)
# | androidMain/kotlin/androidx/compose/ui/text/AndroidComposeUiTextFlags.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/AndroidComposeUiTextFlags.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/AndroidParagraph.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/AndroidParagraph.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/AndroidTextStyle.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/AndroidTextStyle.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/CharHelpers.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/CharHelpers.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/EmojiSupportMatch.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/EmojiSupportMatch.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/Html.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/Html.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/Paragraph.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/Paragraph.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/ParagraphIntrinsics.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/ParagraphIntrinsics.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/Savers.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/Savers.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/BoringLayoutFactory.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/BoringLayoutFactory.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/CharSequenceCharacterIterator.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/CharSequenceCharacterIterator.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/InlineClassUtils.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/InlineClassUtils.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/InternalPlatformTextApi.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/InternalPlatformTextApi.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/LayoutCompat.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/LayoutCompat.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/LayoutHelper.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/LayoutHelper.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/LayoutIntrinsics.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/LayoutIntrinsics.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/ListUtils.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/ListUtils.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/PaintExtensions.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/PaintExtensions.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/SpannedExtensions.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/SpannedExtensions.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/StaticLayoutFactory.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/StaticLayoutFactory.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/TextAndroidCanvas.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/TextAndroidCanvas.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/TextLayout.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/TextLayout.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/TextLayoutGetRangeForRectExtensions.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/TextLayoutGetRangeForRectExtensions.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/selection/SegmentFinder.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/selection/SegmentFinder.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/selection/WordBoundary.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/selection/WordBoundary.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/selection/WordIterator.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/selection/WordIterator.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/BaselineShiftSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/BaselineShiftSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/FontFeatureSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/FontFeatureSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/IndentationFixSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/IndentationFixSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/LetterSpacingSpanEm.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/LetterSpacingSpanEm.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/LetterSpacingSpanPx.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/LetterSpacingSpanPx.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/LineHeightSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/LineHeightSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/LineHeightStyleSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/LineHeightStyleSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/PlaceholderSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/PlaceholderSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/ShadowSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/ShadowSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/SkewXSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/SkewXSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/TextDecorationSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/TextDecorationSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/android/style/TypefaceSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/android/style/TypefaceSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/AndroidFont.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/AndroidFont.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/AndroidFontLoader.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/AndroidFontLoader.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/AndroidFontResolveInterceptor.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/AndroidFontResolveInterceptor.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/AndroidFontUtils.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/AndroidFontUtils.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/AndroidPreloadedFont.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/AndroidPreloadedFont.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/AndroidTypeface.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/AndroidTypeface.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsage.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsage.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/DeviceFontFamilyNameFont.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/DeviceFontFamilyNameFont.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/FontSynthesis.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/FontSynthesis.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/PlatformFontFamilyTypefaceAdapter.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/PlatformFontFamilyTypefaceAdapter.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/PlatformFontVariationSettings.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/PlatformFontVariationSettings.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/font/PlatformTypefaces.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/font/PlatformTypefaces.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/intl/AndroidLocaleDelegate.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/intl/AndroidLocaleDelegate.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/intl/AndroidPlatformLocale.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/intl/AndroidPlatformLocale.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/AndroidAccessibilitySpannableString.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/AndroidAccessibilitySpannableString.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/AndroidDefaultTypeface.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/AndroidDefaultTypeface.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/AndroidFontListTypeface.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/AndroidFontListTypeface.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/AndroidGenericFontFamilyTypeface.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/AndroidGenericFontFamilyTypeface.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/AndroidMultiParagraphDraw.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/AndroidMultiParagraphDraw.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphHelper.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/AndroidParagraphHelper.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/AndroidStringDelegate.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/AndroidStringDelegate.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTextPaint.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/AndroidTextPaint.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTypeface.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/AndroidTypeface.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTypefaceWrapper.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/AndroidTypefaceWrapper.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/EmojiCompatStatus.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/EmojiCompatStatus.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/Synchronization.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/Synchronization.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/URLSpanCache.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/URLSpanCache.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/extensions/LocaleExtensions.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/extensions/LocaleExtensions.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/extensions/PlaceholderExtensions.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/extensions/PlaceholderExtensions.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/extensions/TextPaintExtensions.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/extensions/TextPaintExtensions.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/extensions/TtsAnnotationExtensions.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/extensions/TtsAnnotationExtensions.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/style/BulletSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/style/BulletSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/style/DrawStyleSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/style/DrawStyleSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/platform/style/ShaderBrushSpan.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/platform/style/ShaderBrushSpan.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/style/LineBreak.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/style/LineBreak.android.kt
# | androidMain/kotlin/androidx/compose/ui/text/style/TextMotion.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/text/style/TextMotion.android.kt
# darwinMain (2)
# | darwinMain/kotlin/androidx/compose/ui/text/intl/PlatformLocale.darwin.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/intl/PlatformLocale.darwin.kt
# | darwinMain/kotlin/androidx/compose/ui/text/platform/NativeStringDelegate.darwin.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/platform/NativeStringDelegate.darwin.kt
# desktopMain (15)
# | desktopMain/kotlin/androidx/compose/ui/text/Cache.jvm.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/Cache.jvm.kt
# | desktopMain/kotlin/androidx/compose/ui/text/CharHelpers.jvm.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/CharHelpers.jvm.kt
# | desktopMain/kotlin/androidx/compose/ui/text/WeakReference.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/WeakReference.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/text/font/FontFamily.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/font/FontFamily.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.skiko.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.skiko.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/text/font/FontSynthesis.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/font/FontSynthesis.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/text/intl/DesktopPlatformLocale.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/intl/DesktopPlatformLocale.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/text/platform/AwtFontInterop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/platform/AwtFontInterop.kt
# | desktopMain/kotlin/androidx/compose/ui/text/platform/AwtFontUtils.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/platform/AwtFontUtils.kt
# | desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopFont.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/platform/DesktopFont.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopStringDelegate.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/platform/DesktopStringDelegate.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/text/platform/InternalFontApiChecker.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/platform/InternalFontApiChecker.kt
# | desktopMain/kotlin/androidx/compose/ui/text/platform/JetBrainsRuntimeFontFamilies.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/platform/JetBrainsRuntimeFontFamilies.kt
# | desktopMain/kotlin/androidx/compose/ui/text/platform/ParagraphLayouter.desktop.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/platform/ParagraphLayouter.desktop.kt
# | desktopMain/kotlin/androidx/compose/ui/text/platform/ReflectionUtil.kt -> src/vendor/desktop/kotlin/androidx/compose/ui/text/platform/ReflectionUtil.kt
# iosMain (2)
# | iosMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.ios.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.ios.kt
# | iosMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.ios.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.ios.kt
# jsMain (1)
# | jsMain/kotlin/androidx/compose/ui/text/intl/Actuals.js.kt -> src/vendor/js/kotlin/androidx/compose/ui/text/intl/Actuals.js.kt
# jvmAndAndroidMain (5)
# | jvmAndAndroidMain/kotlin/androidx/compose/ui/text/ActualAtomicReferenceJvm.jvmAndAndroid.kt -> src/vendor/jvmAndAndroid/kotlin/androidx/compose/ui/text/ActualAtomicReferenceJvm.jvmAndAndroid.kt
# | jvmAndAndroidMain/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvmAndAndroid.kt -> src/vendor/jvmAndAndroid/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvmAndAndroid.kt
# | jvmAndAndroidMain/kotlin/androidx/compose/ui/text/input/GapBuffer.jvmAndAndroid.kt -> src/vendor/jvmAndAndroid/kotlin/androidx/compose/ui/text/input/GapBuffer.jvmAndAndroid.kt
# | jvmAndAndroidMain/kotlin/androidx/compose/ui/text/internal/JvmDefaultWithCompatibility.jvmAndAndroid.kt -> src/vendor/jvmAndAndroid/kotlin/androidx/compose/ui/text/internal/JvmDefaultWithCompatibility.jvmAndAndroid.kt
# | jvmAndAndroidMain/kotlin/androidx/compose/ui/text/intl/Locale.jvmAndAndroid.kt -> src/vendor/jvmAndAndroid/kotlin/androidx/compose/ui/text/intl/Locale.jvmAndAndroid.kt
# macosMain (1)
# | macosMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.skiko.macos.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.skiko.macos.kt
# nativeMain (4)
# | nativeMain/kotlin/androidx/compose/ui/text/Cache.native.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/Cache.native.kt
# | nativeMain/kotlin/androidx/compose/ui/text/platform/NativeFont.native.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/platform/NativeFont.native.kt
# | nativeMain/kotlin/androidx/compose/ui/text/platform/ParagraphLayouter.native.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/platform/ParagraphLayouter.native.kt
# | nativeMain/kotlin/androidx/compose/ui/text/platform/PlatformFont.native.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/platform/PlatformFont.native.kt
# skikoMain (17)
# | skikoMain/kotlin/androidx/compose/ui/text/ActualParagraph.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/ActualParagraph.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/Cache.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/Cache.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/CharHelpers.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/CharHelpers.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/FontRasterizationSettings.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/FontRasterizationSettings.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/ParagraphIntrisics.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/ParagraphIntrisics.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/SkiaParagraph.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/SkiaParagraph.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsage.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsage.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/font/PlatformFontFamilyTypefaceAdapter.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/font/PlatformFontFamilyTypefaceAdapter.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/font/SkiaFontLoader.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/font/SkiaFontLoader.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/intl/PlatformLocale.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/intl/PlatformLocale.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/platform/ParagraphBuilder.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/platform/ParagraphBuilder.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/platform/ParagraphLayouter.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/platform/ParagraphLayouter.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/platform/PlatformFont.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/platform/PlatformFont.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaParagraphIntrinsics.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/platform/SkiaParagraphIntrinsics.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaTextPaint.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/platform/SkiaTextPaint.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/text/platform/Synchronization.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/text/platform/Synchronization.skiko.kt
# wasmJsMain (1)
# | wasmJsMain/kotlin/androidx/compose/ui/text/intl/Actuals.wasm.kt -> src/vendor/wasmJs/kotlin/androidx/compose/ui/text/intl/Actuals.wasm.kt
# webMain (10)
# | webMain/kotlin/androidx/compose/ui/text/Cache.web.kt -> src/vendor/web/kotlin/androidx/compose/ui/text/Cache.web.kt
# | webMain/kotlin/androidx/compose/ui/text/WeakReference.web.kt -> src/vendor/web/kotlin/androidx/compose/ui/text/WeakReference.web.kt
# | webMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.skiko.web.kt -> src/vendor/web/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.skiko.web.kt
# | webMain/kotlin/androidx/compose/ui/text/font/FontSynthesis.web.kt -> src/vendor/web/kotlin/androidx/compose/ui/text/font/FontSynthesis.web.kt
# | webMain/kotlin/androidx/compose/ui/text/intl/PlatformLocale.web.kt -> src/vendor/web/kotlin/androidx/compose/ui/text/intl/PlatformLocale.web.kt
# | webMain/kotlin/androidx/compose/ui/text/intl/PreferredLanguages.web.kt -> src/vendor/web/kotlin/androidx/compose/ui/text/intl/PreferredLanguages.web.kt
# | webMain/kotlin/androidx/compose/ui/text/platform/ParagraphLayouter.web.kt -> src/vendor/web/kotlin/androidx/compose/ui/text/platform/ParagraphLayouter.web.kt
# | webMain/kotlin/androidx/compose/ui/text/platform/PlatformFont.web.kt -> src/vendor/web/kotlin/androidx/compose/ui/text/platform/PlatformFont.web.kt
# | webMain/kotlin/androidx/compose/ui/text/platform/WebFont.kt -> src/vendor/web/kotlin/androidx/compose/ui/text/platform/WebFont.kt
# | webMain/kotlin/androidx/compose/ui/text/platform/WebStringDelegate.kt -> src/vendor/web/kotlin/androidx/compose/ui/text/platform/WebStringDelegate.kt
# <<< ---- DIAGNOSTIC GAPS ---- >>>>
@@ -20,9 +20,9 @@ object IconFont {
private val fFonts = mutableMapOf<String, ByteArray>() private val fFonts = mutableMapOf<String, ByteArray>()
// Families that render as single variable-axis glyphs (Material Symbols), // Families that render as single variable-axis glyphs (Material Symbols),
// vs ordinary text fonts. The SDL3 renderer routes only these through its // vs ordinary text fonts — icon families are drawn one codepoint at a time,
// single-glyph FreeType icon path; text families (e.g. a bundled // while text families (e.g. a bundled monospace) go through normal
// monospace) must go through normal full-string rendering. // full-string rendering.
private val fIconFamilies = mutableSetOf<String>() private val fIconFamilies = mutableSetOf<String>()
/** Register a TEXT font family's bytes (rendered as full strings; e.g. a /** Register a TEXT font family's bytes (rendered as full strings; e.g. a
@@ -10,9 +10,8 @@ package com.compose.sdl.text
something the renderer can't deliver. Today the only consumer is the something the renderer can't deliver. Today the only consumer is the
Material Symbols install() path, which emits a one-shot warning when Material Symbols install() path, which emits a one-shot warning when
variable-font axes won't be honoured. The Skia renderer sets variable-font axes won't be honoured. The Skia renderer sets
supportsFontVariations = true via Typeface.makeClone; the SDL3 renderer supportsFontVariations = true via Typeface.makeClone; a renderer that
leaves it false because SDL3_ttf 3.2 has no axis-set API (filename / couldn't honour variable-font axes would leave it false.
iostream / size / face / dpi only).
`supportsFontVariations` is null until a renderer initialises — code `supportsFontVariations` is null until a renderer initialises — code
that warns on install() ignores the null case so it doesn't fire when that warns on install() ignores the null case so it doesn't fire when
@@ -20,7 +20,7 @@ import androidx.compose.ui.text.input.TextFieldValue
SDL_TEXT_INPUT_EVENT), replace this with a real implementation. SDL_TEXT_INPUT_EVENT), replace this with a real implementation.
*/ */
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
internal object NoOpPlatformTextInputService : PlatformTextInputService { object NoOpPlatformTextInputService : PlatformTextInputService {
override fun startInput( override fun startInput(
value: TextFieldValue, value: TextFieldValue,
imeOptions: ImeOptions, imeOptions: ImeOptions,
@@ -10,7 +10,7 @@ package androidx.compose.ui.text.font
* that-isn't-a-FontListFontFamily" adapter. Upstream's skiko actual routes * that-isn't-a-FontListFontFamily" adapter. Upstream's skiko actual routes
* `Default`, `SansSerif`, `Serif`, `Monospace`, `Cursive`, and `LoadedFontFamily` * `Default`, `SansSerif`, `Serif`, `Monospace`, `Cursive`, and `LoadedFontFamily`
* through `SkiaFontLoader` to produce a real `SkTypeface`. Our text renderer * through `SkiaFontLoader` to produce a real `SkTypeface`. Our text renderer
* (SdlParagraph / SkiaParagraph) reads `TextStyle.fontFamily` and * (SkiaParagraph) reads `TextStyle.fontFamily` and
* [com.compose.sdl.text.NamedFont] directly to look the family up * [com.compose.sdl.text.NamedFont] directly to look the family up
* against its registered font table, so the resolver's typeface is never * against its registered font table, so the resolver's typeface is never
* consulted. A no-op adapter (returns an [TypefaceResult.Immutable] wrapping * consulted. A no-op adapter (returns an [TypefaceResult.Immutable] wrapping
@@ -64,4 +64,4 @@ actual class Locale actual constructor(languageTag: String) {
// The OS's most-preferred locale (SDL); en-US before SDL init or on a host that // The OS's most-preferred locale (SDL); en-US before SDL init or on a host that
// reports none. Cheap: the tag list is cached after the first non-empty read. // reports none. Cheap: the tag list is cached after the first non-empty read.
private fun systemCurrentLocale(): Locale = private fun systemCurrentLocale(): Locale =
com.compose.sdl.text.systemPreferredLocaleTags().firstOrNull()?.let(::Locale) ?: Locale("en-US") com.compose.sdl.res.preferredLocaleTagsProvider?.invoke()?.firstOrNull()?.let(::Locale) ?: Locale("en-US")
@@ -17,7 +17,7 @@ internal actual fun createPlatformLocaleDelegate(): PlatformLocaleDelegate =
object : PlatformLocaleDelegate { object : PlatformLocaleDelegate {
override val current: LocaleList override val current: LocaleList
get() { get() {
val tags = com.compose.sdl.text.systemPreferredLocaleTags() val tags = com.compose.sdl.res.preferredLocaleTagsProvider?.invoke().orEmpty()
return if (tags.isEmpty()) LocaleList(listOf(Locale("en-US"))) return if (tags.isEmpty()) LocaleList(listOf(Locale("en-US")))
else LocaleList(tags.map(::Locale)) else LocaleList(tags.map(::Locale))
} }
@@ -2,7 +2,7 @@ package com.compose.sdl.renderer.skia
import androidx.compose.ui.text.font.FontVariation as ComposeFontVariation import androidx.compose.ui.text.font.FontVariation as ComposeFontVariation
import com.compose.sdl.icons.IconFont import com.compose.sdl.icons.IconFont
import com.compose.sdl.loadComposeResourceBytes import com.compose.sdl.res.composeResourceReader
import org.jetbrains.skia.Data import org.jetbrains.skia.Data
import org.jetbrains.skia.FontMgr import org.jetbrains.skia.FontMgr
import org.jetbrains.skia.FontVariation as SkiaFontVariation import org.jetbrains.skia.FontVariation as SkiaFontVariation
@@ -38,7 +38,7 @@ internal object SkiaFonts {
/** Bundled default (NotoSans from data.kres); the fallback for every unresolved family. */ /** Bundled default (NotoSans from data.kres); the fallback for every unresolved family. */
val defaultTypeface: Typeface? = val defaultTypeface: Typeface? =
loadComposeResourceBytes("font/NotoSans.ttf") composeResourceReader?.invoke("font/NotoSans.ttf")
?.let { fontMgr.makeFromData(Data.makeFromBytes(it), 0) } ?.let { fontMgr.makeFromData(Data.makeFromBytes(it), 0) }
?.also { provider.registerTypeface(it, DEFAULT_ALIAS) } ?.also { provider.registerTypeface(it, DEFAULT_ALIAS) }
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:ui-tooling-preview> // Library unique name: <com.bitsycore.compose.ui:ui-tooling-preview>
open annotation class androidx.compose.ui.tooling.preview/AndroidUiMode : kotlin/Annotation { // androidx.compose.ui.tooling.preview/AndroidUiMode|null[0] open annotation class androidx.compose.ui.tooling.preview/AndroidUiMode : kotlin/Annotation { // androidx.compose.ui.tooling.preview/AndroidUiMode|null[0]
constructor <init>() // androidx.compose.ui.tooling.preview/AndroidUiMode.<init>|<init>(){}[0] constructor <init>() // androidx.compose.ui.tooling.preview/AndroidUiMode.<init>|<init>(){}[0]
} }
+1 -1
View File
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:ui-unit> // Library unique name: <com.bitsycore.compose.ui:ui-unit>
open annotation class androidx.compose.ui.unit/ExperimentalUnitApi : kotlin/Annotation { // androidx.compose.ui.unit/ExperimentalUnitApi|null[0] open annotation class androidx.compose.ui.unit/ExperimentalUnitApi : kotlin/Annotation { // androidx.compose.ui.unit/ExperimentalUnitApi|null[0]
constructor <init>() // androidx.compose.ui.unit/ExperimentalUnitApi.<init>|<init>(){}[0] constructor <init>() // androidx.compose.ui.unit/ExperimentalUnitApi.<init>|<init>(){}[0]
} }
+1 -1
View File
@@ -5,7 +5,7 @@
// - Show manifest properties: true // - Show manifest properties: true
// - Show declarations: true // - Show declarations: true
// Library unique name: <com.bitsycore.compose.sdl:ui-util> // Library unique name: <com.bitsycore.compose.ui:ui-util>
open annotation class androidx.compose.ui/ExperimentalComposeUiApi : kotlin/Annotation { // androidx.compose.ui/ExperimentalComposeUiApi|null[0] open annotation class androidx.compose.ui/ExperimentalComposeUiApi : kotlin/Annotation { // androidx.compose.ui/ExperimentalComposeUiApi|null[0]
constructor <init>() // androidx.compose.ui/ExperimentalComposeUiApi.<init>|<init>(){}[0] constructor <init>() // androidx.compose.ui/ExperimentalComposeUiApi.<init>|<init>(){}[0]
} }
File diff suppressed because it is too large Load Diff
+15 -25
View File
@@ -1,6 +1,9 @@
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
// :ui — the Compose base + the Skia rendering pipeline (all native targets). // :ui — the Compose core + the Skia rendering pipeline + the SDL bridges
// (all native targets). androidx.compose.ui.graphics.* / .text.* were split out
// to :ui-graphics / :ui-text, and the sdl3 cinterop now lives in :sdl-core;
// :ui depends on both.
// //
// Source-set hierarchy: // Source-set hierarchy:
// commonMain // commonMain
@@ -12,9 +15,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
// └── skikoRendererMingwMain mingwX64 has no official Skiko klib) → mingwX64 // └── skikoRendererMingwMain mingwX64 has no official Skiko klib) → mingwX64
// //
// SDL3 stays as the windowing / input / platform layer (the single `sdl3` // SDL3 stays as the windowing / input / platform layer (the single `sdl3`
// cinterop). The from-scratch SDL renderer and its SDL3_ttf / SDL3_image / // cinterop, now in :sdl-core). Every target renders through Skia.
// FreeType cinterops were removed — every target now renders through Skia. // `:desktop-native-window` depends only on this module and calls createRenderBackend() /
// `:window` depends only on this module and calls createRenderBackend() /
// rendererPreferredGpuMode(), which resolve to the Skia actuals. // rendererPreferredGpuMode(), which resolve to the Skia actuals.
plugins { plugins {
@@ -23,13 +25,6 @@ plugins {
alias(libs.plugins.compose.multiplatform) alias(libs.plugins.compose.multiplatform)
} }
// SDL3 headers/libs from the in-repo static build tree at <repo>/libs
// (scripts/build-sdl/build-all.py). The .def file is pathless and relies on
// these -I / -libraryPath injections.
val vLibs = "${rootDir.invariantSeparatorsPath}/libs"
val vHostSdlInclude: String = "$vLibs/SDL3/include"
val vSdlLibDir: String = "$vLibs/SDL3/lib"
// Skip mingwX64 on non-Windows hosts; see root build.gradle.kts. // Skip mingwX64 on non-Windows hosts; see root build.gradle.kts.
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
@@ -41,19 +36,6 @@ kotlin {
applyDefaultHierarchyTemplate() applyDefaultHierarchyTemplate()
targets.withType<KotlinNativeTarget>().all {
compilations["main"].cinterops {
// The one SDL3 cinterop — windowing / input / SDL_GetBasePath / … —
// used by every target regardless of GPU path.
create("sdl3") {
defFile(project.file("src/nativeInterop/cinterop/sdl3.def"))
packageName("sdl3")
extraOpts("-compiler-options", "-I$vHostSdlInclude")
extraOpts("-libraryPath", vSdlLibDir)
}
}
}
sourceSets { sourceSets {
commonMain { commonMain {
// Files vendored VERBATIM from upstream Compose by // Files vendored VERBATIM from upstream Compose by
@@ -62,6 +44,8 @@ kotlin {
dependencies { dependencies {
api(project(":ui-util")) api(project(":ui-util"))
api(project(":ui-geometry")) api(project(":ui-geometry"))
api(project(":ui-graphics"))
api(project(":ui-text"))
api(project(":ui-unit")) api(project(":ui-unit"))
api(project(":ui-backhandler")) api(project(":ui-backhandler"))
api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}") api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}")
@@ -82,6 +66,12 @@ kotlin {
// Vendored platform `actual`s + project SDL3 wrappers / Compose native code. // Vendored platform `actual`s + project SDL3 wrappers / Compose native code.
nativeMain { nativeMain {
kotlin.srcDir("src/vendor/native/kotlin") kotlin.srcDir("src/vendor/native/kotlin")
dependencies {
// The sdl3 cinterop now lives in :sdl-core; expose it (api) so :ui's
// SDL platform + renderer code — and :desktop-native-window downstream — see sdl3.*
// and inherit SDL3's static-lib + linker-opt propagation.
api(project(":sdl-core"))
}
} }
// ============ // ============
@@ -116,7 +106,7 @@ kotlin {
dependencies { dependencies {
// Published by the fork's CI to GitHub Packages; version // Published by the fork's CI to GitHub Packages; version
// overridable via -PskikoMingwVersion=. // overridable via -PskikoMingwVersion=.
implementation("org.jetbrains.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse("0.150.1-mingw.1")}") implementation("com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse("0.150.1-mingw.1")}")
} }
} }
val skikoRendererMingwMain = create("skikoRendererMingwMain") { dependsOn(skikoRendererMingwSharedMain) } val skikoRendererMingwMain = create("skikoRendererMingwMain") { dependsOn(skikoRendererMingwSharedMain) }
-224
View File
@@ -406,230 +406,6 @@ skikoMain/kotlin/androidx/compose/ui/skiko/RecordDrawRectRenderDecorator.skiko.k
!skikoMain/kotlin/androidx/compose/ui/window/WindowExceptionHandler.kt !skikoMain/kotlin/androidx/compose/ui/window/WindowExceptionHandler.kt
skikoMain/kotlin/androidx/compose/ui/window/WindowExceptionHandler.kt -> src/vendor/common/kotlin/androidx/compose/ui/window/WindowExceptionHandler.kt skikoMain/kotlin/androidx/compose/ui/window/WindowExceptionHandler.kt -> src/vendor/common/kotlin/androidx/compose/ui/window/WindowExceptionHandler.kt
SET_FOLDER=compose/ui/ui-graphics/src
commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/androidx/compose/ui/graphics/Bezier.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Bezier.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/BlendMode.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/BlendMode.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Brush.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Brush.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Canvas.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Canvas.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/ClipOp.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/ClipOp.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Color.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Color.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/ColorFilter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/ColorFilter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/ColorMatrix.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/ColorMatrix.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Degrees.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Degrees.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/ExperimentalGraphicsApi.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/ExperimentalGraphicsApi.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/FilterQuality.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/FilterQuality.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Float16.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Float16.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/GraphicsContext.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/GraphicsContext.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/ImageBitmap.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/ImageBitmap.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/InlineClassHelper.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/InlineClassHelper.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Interpolatable.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Interpolatable.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/IntervalTree.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/IntervalTree.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/LayerOutsets.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/LayerOutsets.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Matrix.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Matrix.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Outline.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Outline.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Paint.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Paint.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PaintingStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PaintingStyle.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Path.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Path.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathEffect.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathEffect.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathFillType.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathFillType.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathGeometry.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathGeometry.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathHitTester.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathHitTester.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathIterator.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathIterator.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathMeasure.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathMeasure.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathOperation.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathOperation.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathSegment.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathSegment.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PathSvg.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PathSvg.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PixelMap.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PixelMap.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/PointMode.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/PointMode.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/RectangleShape.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/RectangleShape.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/RenderEffect.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/RenderEffect.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Shader.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Shader.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Shadow.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Shadow.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Shape.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Shape.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/StrokeCap.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/StrokeCap.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/StrokeJoin.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/StrokeJoin.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/TileMode.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/TileMode.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/VertexMode.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/VertexMode.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/Vertices.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/Vertices.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Adaptation.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Adaptation.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/ColorModel.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/ColorModel.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpace.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpace.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpaces.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpaces.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Connector.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Connector.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Illuminant.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Illuminant.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Lab.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Lab.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Oklab.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Oklab.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/RenderIntent.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/RenderIntent.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/TransferParameters.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/TransferParameters.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/WhitePoint.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/WhitePoint.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Xyz.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/colorspace/Xyz.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/CanvasDrawScope.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/CanvasDrawScope.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/ContentDrawScope.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/ContentDrawScope.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawContext.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/DrawContext.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawScope.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/DrawScope.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawScopeMarker.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/DrawScopeMarker.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawTransform.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/DrawTransform.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/drawscope/EmptyCanvas.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/drawscope/EmptyCanvas.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/internal/JvmDefaultWithCompatibility.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/internal/JvmDefaultWithCompatibility.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/layer/ChildLayerDependenciesTracker.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/layer/ChildLayerDependenciesTracker.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/layer/CompositingStrategy.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/layer/CompositingStrategy.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayer.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayer.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/painter/BrushPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/painter/BrushPainter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/painter/ColorPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/painter/ColorPainter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/painter/Painter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/painter/Painter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/Blur.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/Blur.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/DropShadowPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/DropShadowPainter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/InnerShadowPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/InnerShadowPainter.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/Shadow.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/Shadow.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/ShadowContext.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/ShadowContext.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/shadow/ShadowRenderer.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/shadow/ShadowRenderer.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/vector/FastFloatParser.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/vector/FastFloatParser.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/vector/PathBuilder.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/vector/PathBuilder.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/vector/PathNode.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/vector/PathNode.kt
# | commonMain/kotlin/androidx/compose/ui/graphics/vector/PathParser.kt -> src/vendor/common/kotlin/androidx/compose/ui/graphics/vector/PathParser.kt
nonJvmMain/kotlin/androidx/compose/ui/graphics/internal/JvmDefaultWithCompatibility.nonJvm.kt -> src/vendor/native/kotlin/androidx/compose/ui/graphics/internal/JvmDefaultWithCompatibility.native.kt
skikoMain/kotlin/ -> src/vendor/skikoRenderer/kotlin/
# | skikoMain/kotlin/androidx/compose/ui/graphics/BlendMode.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/BlendMode.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/ImageBitmap.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/ImageBitmap.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/Matrices.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/Matrices.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/Rects.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/Rects.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedPaint.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedPaint.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedPath.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedPath.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedPathEffect.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedPathEffect.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedPathMeasure.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedPathMeasure.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedRenderEffect.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaBackedRenderEffect.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaColorFilter.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaColorFilter.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaGraphicsContext.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaGraphicsContext.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaImageAsset.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaImageAsset.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaPathIterator.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaPathIterator.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaShader.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaShader.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaTileMode.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaTileMode.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/SkiaVertexMode.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/SkiaVertexMode.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/layer/SkiaGraphicsLayer.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/layer/SkiaGraphicsLayer.skiko.kt
# | skikoMain/kotlin/androidx/compose/ui/graphics/shadow/Blur.skiko.kt -> src/vendor/skikoRenderer/kotlin/androidx/compose/ui/graphics/shadow/Blur.skiko.kt
# B6.1 (2026-07-16): un-refused — skiko leg adopts upstream graphics actuals.
# SkiaBackedCanvas is then MANUAL-VENDORED (moved to src/skikoRendererMain, re-refused
# below) to also implement the port Native* draw contracts. See RENDERER_TASKS.md B6.1.
# B6.2: un-refused — skiko leg adopts upstream GraphicsLayer/GraphicsContext (real
# skiko RenderNode) now the canvas is SkiaBackedCanvas. See RENDERER_TASKS.md B6.2.
!skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt
# B6.1: MANUAL-VENDORED (flattened toBitmap/putBytesInto expect-actuals — see the file).
!skikoMain/kotlin/androidx/compose/ui/graphics/SkiaImageAsset.skiko.kt
SET_FOLDER=compose/ui/ui-text/src
commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/AnnotatedString.kt
# | commonMain/kotlin/androidx/compose/ui/text/AtomicReference.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/AtomicReference.kt
# | commonMain/kotlin/androidx/compose/ui/text/Bullet.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/Bullet.kt
# | commonMain/kotlin/androidx/compose/ui/text/CharHelpers.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/CharHelpers.kt
# | commonMain/kotlin/androidx/compose/ui/text/ExperimentalTextApi.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/ExperimentalTextApi.kt
# | commonMain/kotlin/androidx/compose/ui/text/InternalTextApi.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/InternalTextApi.kt
# | commonMain/kotlin/androidx/compose/ui/text/LinkAnnotation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/LinkAnnotation.kt
# | commonMain/kotlin/androidx/compose/ui/text/LinkInteractionListener.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/LinkInteractionListener.kt
# | commonMain/kotlin/androidx/compose/ui/text/MultiParagraph.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/MultiParagraph.kt
# | commonMain/kotlin/androidx/compose/ui/text/MultiParagraphIntrinsics.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/MultiParagraphIntrinsics.kt
# | commonMain/kotlin/androidx/compose/ui/text/Paragraph.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/Paragraph.kt
# | commonMain/kotlin/androidx/compose/ui/text/ParagraphIntrinsics.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/ParagraphIntrinsics.kt
# | commonMain/kotlin/androidx/compose/ui/text/ParagraphStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/ParagraphStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/Placeholder.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/Placeholder.kt
# | commonMain/kotlin/androidx/compose/ui/text/PlatformTextStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/PlatformTextStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/Savers.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/Savers.kt
# | commonMain/kotlin/androidx/compose/ui/text/SpanStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/SpanStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/String.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/String.kt
# | commonMain/kotlin/androidx/compose/ui/text/StringAnnotation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/StringAnnotation.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextGranularity.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextGranularity.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextInclusionStrategy.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextInclusionStrategy.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextLayoutResult.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextLayoutResult.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextLinkStyles.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextLinkStyles.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextMeasurer.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextPainter.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextRange.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextRange.kt
# | commonMain/kotlin/androidx/compose/ui/text/TextStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/TtsAnnotation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TtsAnnotation.kt
# | commonMain/kotlin/androidx/compose/ui/text/UrlAnnotation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/UrlAnnotation.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsage.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsage.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/Font.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/Font.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontFamily.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontFamily.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontFamilyTypefaceAdapter.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontFamilyTypefaceAdapter.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontLoadingStrategy.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontLoadingStrategy.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontMatcher.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontMatcher.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontSynthesis.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontSynthesis.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontVariation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontVariation.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/FontWeight.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/FontWeight.kt
# | commonMain/kotlin/androidx/compose/ui/text/font/Typeface.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/font/Typeface.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/EditCommand.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/EditCommand.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/EditProcessor.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/EditProcessor.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/EditingBuffer.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/EditingBuffer.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/GapBuffer.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/GapBuffer.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/ImeAction.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/ImeAction.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/ImeOptions.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/ImeOptions.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/InputEventCallback.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/InputEventCallback.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/KeyboardCapitalization.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/KeyboardCapitalization.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/KeyboardType.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/KeyboardType.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/MathUtils.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/MathUtils.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/OffsetMapping.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/OffsetMapping.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/TextFieldValue.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/TextFieldValue.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/TextInputService.kt
# | commonMain/kotlin/androidx/compose/ui/text/input/VisualTransformation.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/input/VisualTransformation.kt
# | commonMain/kotlin/androidx/compose/ui/text/internal/InlineClassHelper.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/internal/InlineClassHelper.kt
# | commonMain/kotlin/androidx/compose/ui/text/internal/JvmDefaultWithCompatibility.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/internal/JvmDefaultWithCompatibility.kt
# | commonMain/kotlin/androidx/compose/ui/text/intl/Locale.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/intl/Locale.kt
# | commonMain/kotlin/androidx/compose/ui/text/intl/LocaleList.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/intl/LocaleList.kt
# | commonMain/kotlin/androidx/compose/ui/text/intl/PlatformLocale.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/intl/PlatformLocale.kt
# | commonMain/kotlin/androidx/compose/ui/text/platform/Dispatcher.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/platform/Dispatcher.kt
# | commonMain/kotlin/androidx/compose/ui/text/platform/PlatformMultiParagraphDraw.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/platform/PlatformMultiParagraphDraw.kt
# | commonMain/kotlin/androidx/compose/ui/text/platform/PlatformString.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/platform/PlatformString.kt
# | commonMain/kotlin/androidx/compose/ui/text/platform/Synchronization.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/platform/Synchronization.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/BaselineShift.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/BaselineShift.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/Hyphens.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/Hyphens.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/LineBreak.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/LineBreak.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/LineHeightStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/LineHeightStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/ResolvedTextDirection.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/ResolvedTextDirection.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextAlign.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextAlign.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextDecoration.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextDecoration.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextDirection.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextDirection.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextForegroundStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextForegroundStyle.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextGeometricTransform.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextGeometricTransform.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextIndent.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextIndent.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextMotion.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextMotion.kt
# | commonMain/kotlin/androidx/compose/ui/text/style/TextOverflow.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/style/TextOverflow.kt
!commonMain/kotlin/androidx/compose/ui/text/platform/Synchronization.kt
nativeMain/kotlin/androidx/compose/ui/text/WeakReference.native.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/WeakReference.native.kt
nativeMain/kotlin/androidx/compose/ui/text/font/FontSynthesis.native.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/font/FontSynthesis.native.kt
nonJvmMain/kotlin/ -> src/vendor/native/kotlin/
# | nonJvmMain/kotlin/androidx/compose/ui/text/AnnotatedString.nonJvm.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/AnnotatedString.nonJvm.kt
# | nonJvmMain/kotlin/androidx/compose/ui/text/AtomicReference.nonJvm.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/AtomicReference.nonJvm.kt
# | nonJvmMain/kotlin/androidx/compose/ui/text/CharHelpers.nonJvm.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/CharHelpers.nonJvm.kt
# | nonJvmMain/kotlin/androidx/compose/ui/text/input/GapBuffer.nonJvmMain.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/input/GapBuffer.nonJvmMain.kt
# | nonJvmMain/kotlin/androidx/compose/ui/text/internal/JvmDefaultWithCompatibility.nonJvmNative.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/internal/JvmDefaultWithCompatibility.nonJvmNative.kt
!nonJvmMain/kotlin/androidx/compose/ui/text/CharHelpers.nonJvm.kt
skikoMain/kotlin/androidx/compose/ui/text/Paragraph.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/Paragraph.native.kt
skikoMain/kotlin/androidx/compose/ui/text/Savers.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/Savers.native.kt
skikoMain/kotlin/androidx/compose/ui/text/TextDecorationLineStyle.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/TextDecorationLineStyle.kt
skikoMain/kotlin/androidx/compose/ui/text/TextStyle.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/TextStyle.native.kt
skikoMain/kotlin/androidx/compose/ui/text/UnresolvedSymbolsRegistry.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/UnresolvedSymbolsRegistry.native.kt
skikoMain/kotlin/androidx/compose/ui/text/WeakReference.skiko.kt -> src/vendor/common/kotlin/androidx/compose/ui/text/WeakReference.kt
skikoMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.native.kt
skikoMain/kotlin/androidx/compose/ui/text/input/PlatformTextInputService2.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/input/PlatformTextInputService2.kt
skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaMultiParagraphDraw.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/platform/SkiaMultiParagraphDraw.native.kt
skikoMain/kotlin/androidx/compose/ui/text/style/LineBreak.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/style/LineBreak.native.kt
skikoMain/kotlin/androidx/compose/ui/text/style/TextMotion.skiko.kt -> src/vendor/native/kotlin/androidx/compose/ui/text/style/TextMotion.native.kt
# >>> ---- DIAGNOSTIC GAPS ---- <<<< # >>> ---- DIAGNOSTIC GAPS ---- <<<<
# androidMain (125) # androidMain (125)
# | androidMain/kotlin/androidx/compose/ui/Actual.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/Actual.android.kt # | androidMain/kotlin/androidx/compose/ui/Actual.android.kt -> src/vendor/android/kotlin/androidx/compose/ui/Actual.android.kt
@@ -1,17 +0,0 @@
package com.compose.sdl.graphics
// ==================
// MARK: NativeFinishableCanvas
// ==================
/**
A renderer canvas that must be flushed once drawing into it is done — SDL batches
geometry and only submits on flush; an offscreen SDL canvas must flush before its
backing texture is read. Implemented by Sdl3Canvas (real flush) and SkiaBackedCanvas
(no-op — Skia save/restore is balanced per call). Lets renderer-agnostic code
(e.g. GraphicsLayer.toImageBitmap) commit an offscreen render without knowing the
concrete canvas type.
*/
interface NativeFinishableCanvas {
fun finish()
}
@@ -1,33 +0,0 @@
package com.compose.sdl.graphics
import androidx.compose.ui.layout.ContentScale
import com.compose.sdl.res.ResourceKind
// ==================
// MARK: NativePainterCanvas bridge
// ==================
/**
Image drawing bridge. Renderer Canvas backends (Sdl3Canvas / SkiaBackedCanvas)
implement this interface to paint a bundled resource by
path + kind. [ResourcePainter] (upstream `Painter` subclass in the res
pipeline) casts the current Canvas to this and calls drawNativePainter from
inside its `Painter.onDraw()` — reached via upstream `Modifier.paint(...)`
(PainterModifier), so the resource render path is driven end-to-end by the
vendored upstream engine.
contentScale is FillBounds when called through PainterModifier (which
pre-scales the size); other values are supported for direct callers.
*/
interface NativePainterCanvas {
fun drawNativePainter(
inResourcePath: String,
inKind: ResourceKind,
inX: Float,
inY: Float,
inWidth: Float,
inHeight: Float,
inContentScale: ContentScale,
inAlpha: Float,
)
}
@@ -6,7 +6,7 @@ import androidx.compose.ui.draganddrop.DragAndDropManager
// MARK: DragAndDropPlatform — SDL event pump hooks // MARK: DragAndDropPlatform — SDL event pump hooks
// ================== // ==================
/** Platform hooks the :window layer's event loop uses to feed SDL_EVENT_DROP_* /** Platform hooks the :desktop-native-window layer's event loop uses to feed SDL_EVENT_DROP_*
* into a per-window DragAndDropManager. The manager instance is created here * into a per-window DragAndDropManager. The manager instance is created here
* (native actual: Sdl3DragAndDropOwner over the SDL drop stream); each dropX * (native actual: Sdl3DragAndDropOwner over the SDL drop stream); each dropX
* extension casts to the concrete platform implementation and no-ops if the * extension casts to the concrete platform implementation and no-ops if the
@@ -8,7 +8,7 @@ import androidx.compose.ui.node.LayoutNode
// ================== // ==================
/** Composition applier over the vendored upstream LayoutNode. /** Composition applier over the vendored upstream LayoutNode.
internal because LayoutNode is internal to :core; the :window layer drives internal because LayoutNode is internal to :core; the :desktop-native-window layer drives
composition through the public ComposeRootHost facade (which upcasts this to composition through the public ComposeRootHost facade (which upcasts this to
Applier<*>). */ Applier<*>). */
internal class NodeApplier(root: LayoutNode) : AbstractApplier<LayoutNode>(root) { internal class NodeApplier(root: LayoutNode) : AbstractApplier<LayoutNode>(root) {
@@ -78,8 +78,8 @@ actual class ClipEntry internal constructor() {
/** Wrap already-PNG-encoded image bytes for [Clipboard.setClipEntry]. /** Wrap already-PNG-encoded image bytes for [Clipboard.setClipEntry].
* The caller owns the encoding — Skia can produce these via * The caller owns the encoding — Skia can produce these via
* `Image.encodeToData(EncodedImageFormat.PNG)`, SDL3_image via * `Image.encodeToData(EncodedImageFormat.PNG)`, or the bytes may come
* `IMG_SavePNG_IO`, or the bytes may come from an app resource. */ * from an app resource. */
fun withImage(pngBytes: ByteArray): ClipEntry = ClipEntry().apply { imageBytes = pngBytes } fun withImage(pngBytes: ByteArray): ClipEntry = ClipEntry().apply { imageBytes = pngBytes }
} }
} }
@@ -206,7 +206,7 @@ private fun sdlWriteEntry(entry: ClipEntry?) {
// The SDL3-backed Clipboard implementation. Singleton because SDL's clipboard // The SDL3-backed Clipboard implementation. Singleton because SDL's clipboard
// is process-global — allocating a new one per Window() would only waste // is process-global — allocating a new one per Window() would only waste
// memory. Consumed by :window when seeding LocalClipboard. // memory. Consumed by :desktop-native-window when seeding LocalClipboard.
private object SDL3Clipboard : Clipboard { private object SDL3Clipboard : Clipboard {
override suspend fun getClipEntry(): ClipEntry? = sdlReadEntry() override suspend fun getClipEntry(): ClipEntry? = sdlReadEntry()
override suspend fun setClipEntry(clipEntry: ClipEntry?) { sdlWriteEntry(clipEntry) } override suspend fun setClipEntry(clipEntry: ClipEntry?) { sdlWriteEntry(clipEntry) }
@@ -144,7 +144,7 @@ class ComposeNativeWindow constructor(
// ============ // ============
// Framework hooks — driven by composeWindow's main loop (which lives in // Framework hooks — driven by composeWindow's main loop (which lives in
// the :window module, so these are public rather than internal). Not // the :desktop-native-window module, so these are public rather than internal). Not
// intended for app code. // intended for app code.
fun onResized() { fun onResized() {

Some files were not shown because too many files have changed in this diff Show More