Compare commits

...
14 Commits
Author SHA1 Message Date
Bitsy 10380e5422 fix(text): forward topRatio to skiko so inherited lineHeight centres like upstream
Text with a lineHeight much larger than its fontSize sat visibly LOW on native
compared to the JVM reference - most obvious on apidemo's SourceTag pill, whose
Text sets fontSize = 9.sp but inherits Material 3 bodyLarge's 24.sp lineHeight.

Upstream's ParagraphBuilder.skiko.kt sets `res.topRatio = topRatio` on every
SkTextStyle, sourced from LineHeightStyle.Alignment.topRatio. The port set
`ts.height` and the paragraph `heightMode` but never set topRatio, so skiko fell
back to its own default (-1 = split the extra leading proportionally to the
font's ascent:descent). Proportional splitting puts most of a large leading
ABOVE the glyphs; Material 3's type styles ask for Alignment.Center (0.5).

Fallback is Alignment.Proportional, matching upstream, so text that specifies no
lineHeightStyle keeps its current spacing. topRatio exists on both the official
skiko and the bitsycore mingw fork, so all four targets compile.

Measured on apidemo at 1240x820, native vs jvm over the whole window:
  before  2.94% of pixels differ, 2.14% by >32/255
  after   1.52% of pixels differ, 0.29% by >32/255
The pills are now pixel-identical and the residual is rasterizer AA.

This also resolves the "constant ~2px vertical offset" logged next to it: that
was the same bug compounding through stacked text rows, not a separate issue.
Before the fix, shifting the jvm capture down 2px HALVED the error; now 0px is
strictly best (0.29% vs 2.13% at +1px).

Found via the apidemo --screenshot drift check added in the previous commit.
2026-09-12 01:57:23 +02:00
Bitsy 2fe26cf7f8 docs(plan): root-cause the residual pill mis-centering to leading distribution
Aligning the default font (7a) removed the different-typeface confound - glyph
ink is now 7 rows on both stacks - but the SourceTag pill text still sits low
on native. Measured: jvm line box 24px with 10/9 gaps, native 25px with 13/7.

Decisive test: adding an explicit lineHeight = 9.sp, so there is no extra
leading to distribute, makes the two stacks PIXEL-IDENTICAL (same 14px box,
same ink rows, same 4/3 gaps). The Text only sets fontSize, so it inherits
M3 bodyLarge's 24.sp lineHeight - a line box far taller than the glyphs.

So font metrics, glyph raster and baseline placement are all correct; the
divergence is isolated to the leading-distribution path, which both adds a
pixel to the box and biases the glyphs downward. Pointed at the heightMode
branch in SkiaParagraphEngine and the per-run height multiplier, with an
explicit warning not to paper over it by pinning lineHeight at call sites.
2026-09-12 01:34:55 +02:00
Bitsy 71aab5d502 docs(bridge): correct the stated relationship between the two bridge halves
The comment added with the ecosystem rules claimed the plugin table and the
repo-internal FULL-COMMONIZATION BRIDGE must match each other exactly. They
must not, and a cross-check shows they already do not: animation-graphics,
material-ripple and ui-backhandler have plugin rules but no root rule.

That asymmetry is correct. The plugin table has to cover every coordinate the
port PUBLISHES, since a consumer can declare any of them; the root build only
needs a rule where an IN-REPO module declares a Maven coordinate in commonMain,
and in-repo modules reach those three through project(...) instead. Restated
the real invariant: a published coordinate missing from the PLUGIN table is the
error to look for.

Verified: 32 of 35 published modules are substitutable, and the 3 that are not
(sdl-core, material-symbols, desktop-native-window) are exactly the modules
with no upstream coordinate to substitute from.
2026-09-12 01:29:18 +02:00
Bitsy d19948059b fix(apidemo): align the default font across both stacks; add headless drift capture
The SourceTag pill looked vertically centred on jvm and off-centre on native.
Not a centering bug: the pill is Box(padding(vertical = 1.dp)) { Text(9.sp) }
with no centering logic, so glyph position is decided purely by font metrics -
and the two stacks were drawing it in DIFFERENT TYPEFACES. Native resolves
FontFamily.Default to the bundled NotoSans (SkiaFonts.defaultTypeface is the
fallback for every unresolved family); the jvm leg only ever registered
monoFontFamily, so Default was a system face (Segoe UI on Windows).

That made it a parity-harness defect, not a renderer bug - and a broad one,
since every Text without an explicit fontFamily was being compared against the
wrong reference.

Fixed with a defaultFontFamily expect/actual loading the bundled NotoSans on
both legs, stamped across the M3 Typography (withDefaultFontFamily) because
typography styles carry their own fontFamily and overriding LocalTextStyle
alone would not reach them. This is the same treatment :demo's parity leg has
had all along (its notoSans/notoTypography block says as much); apidemo had
simply never been given it.

Drift capture: :apidemo could not screenshot itself, so both legs now take
--screenshot=<path> and render OFFSCREEN to quiescence - native via a GPU
framebuffer readback, jvm via ImageComposeScene - with a virtual 60fps clock
and infinite animations frozen, mirroring :demo's parity path. Neither needs a
visible window (a screen-scrape approach was tried first and captured whatever
happened to be in front of the app, so it was dropped).

First measured run, 1240x820: 2.9% of pixels differ at all, 2.1% by >32/255.
Two residuals recorded in PLAN.md 7a-bis, neither a text-metrics bug: a
constant ~2px vertical offset that accounts for about half of all remaining
drift, and a Material Symbols glyph missing from the subsetted font in the
session header (tofu on jvm, nothing on native).

Bmp.kt is duplicated from :demo rather than promoted to a library module: it is
app-level tooling and :ui-graphics deliberately does not re-export skiko.
2026-09-12 01:23:34 +02:00
Bitsy 20714b3eeb chore(deps): version sweep against CMP 1.12.0; restructure the version catalog
Applies an explicit policy, now written at the top of libs.versions.toml:
anything Compose Multiplatform integrates is pinned to what CMP ships (for the
androidx mirrors, the JETPACK version CMP's release notes map its
org.jetbrains.androidx.* artifact to, since this port consumes the google
coordinates); anything CMP does not integrate is pinned to the latest release;
deliberate exceptions are allowed but must be commented.

Checked every pin against upstream rather than against memory - the CMP core
catalog at v1.12.0 plus the actual dependency declarations of the vendored
modules:

  kotlin               2.4.0        -> 2.4.20   latest; builds + links clean,
                                                no klib API diff
  okio                 3.17.0       -> 3.18.2   latest
  ktor                 3.5.1        -> 3.5.2    latest
  navigation3-runtime  1.2.0-alpha05 -> alpha04  CMP ships jb 1.2.0-alpha02 ==
                                                Jetpack alpha04; do not drift on
                                                a pre-release line
  collection 1.5.0, graphics-shapes 1.1.0, lifecycle 2.11.0, skiko 0.150.1,
  koin 4.2.2, coil 3.6.2, SDL3 3.4.16           already correct

savedstate stays at 1.5.0 as a DOCUMENTED exception: CMP builds against 1.4.0
and lifecycle 2.11.0 requires 1.4.0, but only as a MINIMUM, so 1.5.0 resolves
with no conflict and hands consumers the newer API. navigationevent stays at
1.1.2, the latest patch of the 1.1 minor CMP ships.

The catalog is now sectioned (toolchain / CMP / skia / androidx / vendored /
infrastructure) with each group carrying the reason it is pinned where it is,
so the next sweep is mechanical. README's pinned-versions tables updated to
match, including the policy statement.
2026-09-12 01:23:15 +02:00
Bitsy d029b48e10 docs(readme): add a pinned-versions table; centralise every androidx pin
The table covers the toolchain (Kotlin, Compose Multiplatform, SDL3, both skiko
builds), the Compose libraries with official-vs-port coordinates side by side,
the vendored ecosystem libraries with the reason each one is vendored, the
androidx artifacts used as-is, and the infrastructure pins.

To make that table a contract rather than prose, every androidx coordinate now
comes from the version catalog instead of being written literally in six build
files. That surfaced a real inconsistency: androidx.navigation3:navigation3-runtime
was pinned at 1.1.4 in :compose:ui:ui and demo's commonMain but 1.2.0-alpha05 in
:navigation3:navigation3-ui and demo's jvmMain. Gradle resolved the conflict to
the highest, so the build was fine, but nothing said which was intended - now
there is one entry.

Also records WHY Kotlin stays on 2.4.0 rather than dropping to the 2.2.20 that
CMP 1.12.0 is built with, and why material3 is 1.12.0-alpha03 at CMP 1.12.0.
2026-09-12 00:42:40 +02:00
Bitsy 47445ab7ab docs: document the vendored ecosystem libraries + the VENDOR-REIMPL convention
feat(bridge): substitute Koin / Coil 3 / Pulse MVI for consumers too

The consumer-facing bridge plugin's table only covered Compose, so a third-party
app declaring io.insert-koin / io.coil-kt.coil3 / com.bitsycore.lib coordinates
would have resolved the upstream artifacts and failed on mingwX64. Added all 15
entries, with a note that the plugin table and the repo-internal
FULL-COMMONIZATION BRIDGE are two halves of the same swap and must stay in sync.

Docs:
- CLAUDE.md: koin/ coil/ pulse/ in the module map (including WHY each is
  vendored and the source-set / skiko-branch shapes), the five pinned upstream
  repos, and the "check BOTH coordinate sets" rule with the duplicate-classes
  hazard that follows from it.
- CLAUDE.md: the VENDOR-REIMPL marker next to VENDOR-BASE in the vendoring
  rules - a reimplementation is deliberately not drift-tracked, only a
  SIGNATURE change matters.
- README.md: a table of what is vendored and why, so the answer to "does X work
  on this port" is visible without reading CLAUDE.md.
- TOOLING.md: audit-exclusions.py alongside the other two guardrails, the
  ecosystem refs in the version map, and the ref-bump runbook generalised off
  Compose-only.
- bridge README: the ecosystem coordinates a consumer can declare, plus the two
  caveats (nav2 is a dead end; pick one lifecycle coordinate set).
- PLAN.md 7b: marked done, with the three findings worth remembering.
2026-09-12 00:39:04 +02:00
Bitsy b965c505ee feat(pulse): vendor the Pulse MVI stack for Kotlin/Native desktop
bitsycore/pulse-mvi targets android / jvm / ios / js / wasm and publishes NO
desktop-native artifact at all, so all four modules are vendored:

  :pulse:pulse             the MVI core (store, state, intents)
  :pulse:pulse-viewmodel   ViewModel binding
  :pulse:pulse-savedstate  SavedStateHandle persistence
  :pulse:pulse-compose     Compose bindings

Vendored VERBATIM @ 0.3.7 (new PULSE_REF pin + manifests); 14 files, commonMain
only, zero local edits. Pinned to the TAG, not main: the three commits past
0.3.7 are docs and CI only, and a tag is the durable ref this repo's vendoring
rules ask for.

GOOGLE lifecycle coordinates again, not upstream's org.jetbrains.androidx.*
mirrors - same duplicate-classes reason as the Koin modules.

COORDINATES: upstream publishes com.bitsycore.lib:*, which this repo must not
republish under the same name. The port publishes com.bitsycore.pulse:* instead
and the bridge substitutes com.bitsycore.lib:* -> the project modules on native
configurations, so consumers keep declaring the upstream coordinate.
2026-09-12 00:35:30 +02:00
Bitsy 05faaa7f7c feat(coil): vendor the Coil 3 stack for Kotlin/Native desktop
Coil 3.6.2 publishes linux + apple klibs for its core/network/svg modules but
NO mingwX64 anywhere, and NO desktop-native artifact at all for the compose
layer. The sources are target-agnostic, so the port re-declares the targets and
rebuilds them:

  :coil:coil-core            coil3.* core (Skia-based decoding)
  :coil:coil                 the singleton ImageLoader facade
  :coil:coil-compose-core    AsyncImage / rememberAsyncImagePainter internals
  :coil:coil-compose         the public compose entry points
  :coil:coil-svg             SVG decoding via skiko SVGDOM
  :coil:coil-network-core    shared network-fetcher plumbing
  :coil:coil-network-ktor3   Ktor 3 fetcher, on the port's existing ktor pin

Vendored VERBATIM from coil-kt/coil @ 3.6.2 (new COIL_REF pin + manifests);
152 files, zero local edits - all of it compiled unmodified.

SOURCE-SET COLLAPSE: the port has no android, jvm or js target, so upstream's
nonAndroidMain / nonJvmCommonMain / nonJsCommonMain all apply to every target
here. They do NOT merge into nativeMain though: several declare `expect`s whose
`actual`s live in upstream nativeMain, and siblings in one source set is a hard
error. So they keep their own level above it.

TWO PARALLEL SKIKO BRANCHES in coil-core / coil-svg / coil-compose-core:
upstream's non-android code uses org.jetbrains.skia.* directly, so the
INTERMEDIATE source set holding it needs skiko on its own compile classpath (a
shared-metadata compilation is a real compile). macOS/Linux take the official
skiko and mingwX64 takes the bitsycore fork, and the two cannot share an
intermediate - so mingw gets a parallel branch over the same srcDirs, the same
shape :compose:ui:ui-graphics already uses. Kotlin emits no metadata
compilation for the single-target fork branch, so the two never collide.

coil-compose-core declares the whole ui / foundation family DIRECTLY rather
than leaning on foundation's transitives - the granular-metadata trap from
CLAUDE.md's "Common pitfalls": a substituted coord's transitives drop off the
commonMain metadata classpath.

Published as com.bitsycore.coil3:<module>; bridge substitution rules added so
consumers keep declaring the official io.coil-kt.coil3 coordinates.
2026-09-12 00:30:01 +02:00
Bitsy 59bb159351 feat(koin): vendor the Koin modules that stop at apple+android upstream
koin-core 4.2.2 already publishes mingwX64 + linux klibs, so it stays a plain
Maven dependency. These four do not, and their sources are platform-agnostic,
so the port rebuilds the same code for its desktop targets:

  :koin:koin-core-viewmodel      org.koin.viewmodel.* + module DSL
  :koin:koin-compose             org.koin.compose.*
  :koin:koin-compose-viewmodel   org.koin.compose.viewmodel.*
  :koin:koin-compose-navigation3 org.koin.compose.navigation3.*

Vendored VERBATIM from InsertKoinIO/koin @ 4.2.2 (new KOIN_REF pin + manifests);
36 files, no local edits needed - everything compiled for mingwX64 unmodified.

NAV3, NOT NAV2: the requested koin-compose-viewmodel-navigation sits on nav2's
navigation-compose, which publishes no mingwX64/linux klibs under EITHER the
androidx.* or org.jetbrains.androidx.* coordinates - it cannot reach this port's
targets without vendoring nav2 too. This port's navigation story is Navigation 3
(:navigation3:navigation3-ui), and koin-compose-navigation3 needs only
koin-compose + navigation3-runtime, both already reachable. Vendored that instead.

GOOGLE lifecycle coordinates (androidx.lifecycle:*), not the
org.jetbrains.androidx.* mirrors upstream koin uses: the port already resolves
the google ones, and mixing both puts the same classes on the path twice.

Published as com.bitsycore.koin:<module>; bridge substitution rules added so
consumers keep declaring the official io.insert-koin coordinates.
2026-09-12 00:19:39 +02:00
Bitsy fcba77b622 docs(plan): record the JVM default-font parity defect + the Koin/Coil vendoring audit
7a: the apidemo SourceTag pill divergence is a font-resolution difference, not a
centering bug - native FontFamily.Default is the bundled NotoSans (SkiaFonts.
defaultTypeface), the JVM leg never registers it so Default is the system font.
Every un-familied Text is being compared against a different typeface.

7b: target-availability table for the requested libraries. navigationevent-compose
needs NO vendoring (both coordinate sets ship mingwX64 + linux + macos, and the
port already consumes it); Koin needs 4 modules, Coil3 needs 7.
2026-09-12 00:05:18 +02:00
Bitsy 82ffd7cf4d feat: migrate to Compose Multiplatform 1.12.0 + SDL3 3.4.16
Upstream baseline
- Pin both vendored refs to the STABLE v1.12.0 tag (core + umbrella); the
  native and JVM-parity legs are back in lockstep, no dev-build skew.
- Catalog: compose 1.12.0, composeRuntime 1.12.0. material3 stays
  1.12.0-alpha03 - that IS the version CMP 1.12.0 ships (its own train).
- Re-synced 1560 vendored files; drift + vendor-clean both clean.
- Retire the SelectionLayout.kt manual vendor: upstream fixed the same
  out-of-bounds at the source (lastSlot = currentSlot, not currentSlot + 1),
  so the fork's index clamps are redundant. Back to verbatim vendoring.
- Re-stamp 10 manual vendors to @ v1.12.0 (upstream unchanged base..pin).
- Regenerate the klib API dumps. These had already drifted on main (the last
  dump predates the scrollbar / IME changes), so the diff covers that too.

SDL3 3.4.16, skiko fork 0.150.1-mingw.2
- Rebuild the static libSDL3.a from release-3.4.16.
- CMP 1.12.0 uses skiko 0.150.1, unchanged, so the fork's Skia base still
  matches; bump to the -mingw.2 build and centralise it as `skikoMingw` in
  the version catalog instead of three hardcoded copies.
- Resolve the fork from the PUBLIC maven.bitsycore.com/releases instead of
  the credentialed GitHub Packages repo: building the Windows target no
  longer needs a GitHub token.

Gradle module paths mirror the directory
- Drop every projectDir redirect: :ui -> :compose:ui:ui,
  :animation-core -> :compose:animation:animation-core, and so on.
- INVARIANT (documented in settings.gradle.kts + CLAUDE.md): the leaf
  directory IS the published artifactId. KMP derives a target publication's
  coordinate as <project.name>-<target>, and a target disabled on the
  building host (all Apple targets on Windows) has no publication object to
  retarget - while the root kotlinMultiplatform metadata, which the WINDOWS
  publish job owns, still emits an available-at for it. A mismatched leaf
  silently ships a root module pointing at a nonexistent <leaf>-macosarm64.
  So compose/desktop/native/window and components/resources/library are
  renamed to their artifactIds. Published coordinates are unchanged.

Manual-vendor audit
- New scripts/compose-fork/audit-exclusions.py: classifies every `!` manifest
  exclusion as manual vendor (VENDOR-BASE, drift-tracked), reimplementation
  (VENDOR-REIMPL, deliberately not tracked), or orphan, and fails on any
  unclassified one.
- 14 project reimplementations were invisible to the drift checker by
  accident; mark them VENDOR-REIMPL. None needed reconciling (all verified
  <= 0.53 similarity to their upstream counterparts, none changed upstream
  between the old pin and v1.12.0).

Fix the JVM apidemo build
- Declare components-resources on jvmMain (decodeToImageBitmap /
  decodeToSvgPainter) and add the two missing cross-package imports. The JVM
  parity target had never compiled.

Verified on Windows: both native executables link and render, apidemo JVM
builds and launches, apiCheck green, common metadata compiles (the Windows
publish gate), publishToMavenLocal emits the same coordinates as before.
2026-09-12 00:03:13 +02:00
Bitsy d3eef74803 build: update Gradle wrapper to version 9.7.1 and add toolchain configuration 2026-09-11 23:29:20 +02:00
Bitsy a07f4634b2 chore: add local.properties to .gitignore 2026-09-11 23:21:23 +02:00
133 changed files with 4874 additions and 1157 deletions
+1
View File
@@ -64,3 +64,4 @@ __pycache__/
# Probe artifacts written to the repo root by demo --nav3test / --searchesctest / --dialoganimtest # Probe artifacts written to the repo root by demo --nav3test / --searchesctest / --dialoganimtest
/*.bmp /*.bmp
/local.properties
+136 -35
View File
@@ -38,8 +38,8 @@ Rendering is **Skia everywhere** behind one `RenderBackend` - Metal / OpenGL
- **macOS + Linux** link the OFFICIAL Skiko klibs from Maven. - **macOS + Linux** link the OFFICIAL Skiko klibs from Maven.
- **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 https://maven.bitsycore.com/releases as
`com.bitsycore.skiko:skiko:0.150.1-mingw.1` (override with `com.bitsycore.skiko:skiko:0.150.1-mingw.2` (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`). the bridge plugin (`installWindowsSkiaDll`).
@@ -57,59 +57,60 @@ Library modules mirror upstream Compose Multiplatform's `compose/` tree.
The SDL layer is two modules: `:sdl-core` (the NAKED sdl3 cinterop + platform The SDL layer is two modules: `:sdl-core` (the NAKED sdl3 cinterop + platform
primitives - zero Compose dep, like `skiko`) at `sdl/sdl-core/`, and primitives - zero Compose dep, like `skiko`) at `sdl/sdl-core/`, and
`:desktop-native-window` (the SDL3 main-loop shell + app entry point) at `:desktop-native-window` (the SDL3 main-loop shell + app entry point) at
`compose/desktop/native/window/`. `:ui` depends on `:sdl-core` and its renderer `compose/desktop/native/desktop-native-window/`. `:ui` depends on `:sdl-core` and its renderer
+ SDL↔Compose bridges pick the cinterop from it. + 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, and the gradle path mirrors the directory (no `projectDir`
redirection).
``` ```
compose/ compose/
├── ui/ ├── ui/
│ ├── ui/ → :ui - androidx.compose.ui.* CORE (Modifier, LayoutNode, │ ├── ui/ → :compose:ui:ui - androidx.compose.ui.* CORE (Modifier, LayoutNode,
│ │ composition, semantics, input, focus) + com.compose.sdl.* - │ │ composition, semantics, input, focus) + com.compose.sdl.* -
│ │ the Skia RenderBackend + GPU bridges + the SDL↔Compose │ │ the Skia RenderBackend + GPU bridges + the SDL↔Compose
│ │ bridges (events / clipboard / cursors / window). Depends on │ │ bridges (events / clipboard / cursors / window). Depends on
│ │ :ui-graphics, :ui-text, :sdl-core. (ui-graphics + ui-text + │ │ :ui-graphics, :ui-text, :sdl-core. (ui-graphics + ui-text +
│ │ the sdl3 cinterop were split OUT - upstream layout.) │ │ the sdl3 cinterop were split OUT - upstream layout.)
│ ├── ui-graphics/ → :ui-graphics - androidx.compose.ui.graphics.* + the Skia actuals │ ├── ui-graphics/ → :compose:ui:ui-graphics - androidx.compose.ui.graphics.* + the Skia actuals
│ │ (SkiaBackedCanvas/Path/Paint, GraphicsLayer, SkiaImageCache, │ │ (SkiaBackedCanvas/Path/Paint, GraphicsLayer, SkiaImageCache,
│ │ painter/image + resource seams). → skiko; SDL-free. │ │ painter/image + resource seams). → skiko; SDL-free.
│ ├── ui-text/ → :ui-text - androidx.compose.ui.text.* + the skiko text engine │ ├── ui-text/ → :compose:ui:ui-text - androidx.compose.ui.text.* + the skiko text engine
│ │ (SkiaParagraph → NativeParagraphOps → SkiaFonts, IconFont, │ │ (SkiaParagraph → NativeParagraphOps → SkiaFonts, IconFont,
│ │ NamedFont). → :ui-graphics, skiko; SDL-free. │ │ NamedFont). → :ui-graphics, skiko; SDL-free.
│ ├── ui-util/ → :ui-util - androidx.compose.ui.util.* (+ Experimental/InternalComposeUiApi) │ ├── ui-util/ → :compose:ui:ui-util - androidx.compose.ui.util.* (+ Experimental/InternalComposeUiApi)
│ ├── ui-geometry/ → :ui-geometry - androidx.compose.ui.geometry.* │ ├── ui-geometry/ → :compose:ui:ui-geometry - androidx.compose.ui.geometry.*
│ ├── ui-unit/ → :ui-unit - androidx.compose.ui.unit.* │ ├── ui-unit/ → :compose:ui:ui-unit - androidx.compose.ui.unit.*
│ ├── ui-backhandler/ → :ui-backhandler - androidx.compose.ui.backhandler.* │ ├── ui-backhandler/ → :compose:ui:ui-backhandler - androidx.compose.ui.backhandler.*
│ └── ui-tooling-preview/ → :ui-tooling-preview - androidx.compose.ui.tooling.preview.* │ └── ui-tooling-preview/ → :compose:ui:ui-tooling-preview - androidx.compose.ui.tooling.preview.*
│ (the common @Preview + PreviewParameterProvider, │ (the common @Preview + PreviewParameterProvider,
│ vendored verbatim; the Maven artifact ships no │ vendored verbatim; the Maven artifact ships no
│ mingwX64/linux klibs). IDE-only metadata - previews │ mingwX64/linux klibs). IDE-only metadata - previews
│ render through the apps' jvm parity targets. │ render through the apps' jvm parity targets.
├── animation/ ├── animation/
│ ├── animation-core/ → :animation-core - androidx.compose.animation.core.* │ ├── animation-core/ → :compose:animation:animation-core - androidx.compose.animation.core.*
│ ├── animation/ → :animation - androidx.compose.animation.* (non-core) │ ├── animation/ → :compose:animation:animation - androidx.compose.animation.* (non-core)
│ └── animation-graphics/ → :animation-graphics - androidx.compose.animation.graphics.* │ └── animation-graphics/ → :compose:animation:animation-graphics - androidx.compose.animation.graphics.*
├── foundation/ ├── foundation/
│ ├── foundation/ → :foundation - androidx.compose.foundation.* │ ├── foundation/ → :compose:foundation:foundation - androidx.compose.foundation.*
│ └── foundation-layout/ → :foundation-layout - androidx.compose.foundation.layout.* │ └── foundation-layout/ → :compose:foundation:foundation-layout - androidx.compose.foundation.layout.*
├── material3/ ├── material3/
│ └── material3/ → :material3 - androidx.compose.material3.* │ └── material3/ → :compose:material3:material3 - androidx.compose.material3.*
├── material/ ├── material/
│ └── material-ripple/ → :material-ripple - androidx.compose.material.ripple.* │ └── material-ripple/ → :compose:material:material-ripple - androidx.compose.material.ripple.*
└── desktop/native/window/ → :desktop-native-window - nativeComposeApp { Window(...) {} } └── desktop/native/desktop-native-window/ → :compose:desktop:native:desktop-native-window - nativeComposeApp { Window(...) {} }
multi-window shell + SDL3 main loop; nativeComposeWindow() multi-window shell + SDL3 main loop; nativeComposeWindow()
wrapper (project app-shell, not an upstream CMP artifact). wrapper (project app-shell, not an upstream CMP artifact).
Published as com.bitsycore.compose:desktop-native-window. Published as com.bitsycore.compose:desktop-native-window.
sdl/ sdl/
└── sdl-core/ → :sdl-core - the NAKED sdl3 cinterop + platform primitives └── sdl-core/ → :sdl:sdl-core - the NAKED sdl3 cinterop + platform primitives
(zero Compose dep, like skiko); the single `sdl3` cinterop (zero Compose dep, like skiko); the single `sdl3` cinterop
lives here. :ui depends on it. com.bitsycore.compose.sdl:sdl-core. 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/ → :utils:material-symbols - codepoints + all three style objects
(Outlined / Rounded / Sharp). COMMON API (usable from (Outlined / Rounded / Sharp). COMMON API (usable from
shared app code) + per-stack actuals: native renders shared app code) + per-stack actuals: native renders
via :foundation IconFontIcon (Skia), jvm() via Skiko directly via :foundation IconFontIcon (Skia), jvm() via Skiko directly
@@ -127,7 +128,7 @@ utils/
jvmProcessResources stages the same fonts (jvm). jvmProcessResources stages the same fonts (jvm).
components/ components/
└── resources/library/ → :components-resources - the OFFICIAL Compose resources └── resources/components-resources/ → :components:resources:components-resources - the OFFICIAL Compose resources
runtime (org.jetbrains.compose.components: runtime (org.jetbrains.compose.components:
components-resources), VENDORED from the components-resources), VENDORED from the
compose-multiplatform UMBRELLA repo (the first compose-multiplatform UMBRELLA repo (the first
@@ -140,8 +141,56 @@ components/
Apps' JVM targets keep the Maven artifact - the Apps' JVM targets keep the Maven artifact - the
generated Res accessors work against BOTH. generated Res accessors work against BOTH.
koin/ → the Koin DI modules upstream stops publishing for desktop native.
├── koin-core-viewmodel/ → :koin:koin-core-viewmodel - org.koin.viewmodel.* + module DSL
├── koin-compose/ → :koin:koin-compose - org.koin.compose.*
├── koin-compose-viewmodel/ → :koin:koin-compose-viewmodel - org.koin.compose.viewmodel.*
└── koin-compose-navigation3/ → :koin:koin-compose-navigation3 - org.koin.compose.navigation3.*
VENDORED verbatim from InsertKoinIO/koin
(KOIN_REF). koin-core ITSELF publishes mingwX64
+ linux and is a plain Maven dep - only these
four stop at apple+android upstream. NOTE it is
the NAV3 module, not koin-compose-viewmodel-
navigation: that one sits on nav2's
navigation-compose, which has no mingwX64/linux
klibs under EITHER coordinate set.
com.bitsycore.koin:<module>.
coil/ → Coil 3 image loading. Upstream ships linux but NO mingwX64 for
│ core/network/svg, and NO desktop native at all for the compose
│ layer. VENDORED verbatim from coil-kt/coil (COIL_REF).
├── coil-core/ → :coil:coil-core - coil3.* core, Skia-based decode
├── coil/ → :coil:coil - singleton ImageLoader facade
├── coil-compose-core/ → :coil:coil-compose-core - AsyncImage internals
├── coil-compose/ → :coil:coil-compose - public compose entry points
├── coil-svg/ → :coil:coil-svg - SVG via skiko SVGDOM
├── coil-network-core/ → :coil:coil-network-core - fetcher plumbing
└── coil-network-ktor3/ → :coil:coil-network-ktor3 - Ktor 3 fetcher
Upstream's nonAndroid / nonJvmCommon /
nonJsCommon sets all apply here (no android /
jvm / js target) but must stay ABOVE nativeMain
- they declare expects whose actuals live in
nativeMain. coil-core / coil-svg /
coil-compose-core use org.jetbrains.skia
directly, so they carry TWO PARALLEL skiko
branches (official for macOS/Linux, the
bitsycore fork for mingwX64) exactly like
:compose:ui:ui-graphics. com.bitsycore.coil3:<m>.
pulse/ → Pulse MVI. Upstream (bitsycore/pulse-mvi, PULSE_REF) targets
│ android / jvm / ios / js / wasm and publishes NO desktop-native
│ artifact, so all four modules are vendored. commonMain only.
├── pulse/ → :pulse:pulse - MVI core (store/state/intents)
├── pulse-viewmodel/ → :pulse:pulse-viewmodel - ViewModel binding
├── pulse-savedstate/ → :pulse:pulse-savedstate - SavedStateHandle persistence
└── pulse-compose/ → :pulse:pulse-compose - Compose bindings
Published as com.bitsycore.pulse:<module>, NOT
upstream's com.bitsycore.lib:<module> - the two
must not collide; the bridge substitutes the
upstream coord on native configs.
navigation3/ navigation3/
└── navigation3-ui/ → :navigation3-ui - androidx.navigation3.ui.* + scene machinery, └── navigation3-ui/ → :navigation3:navigation3-ui - androidx.navigation3.ui.* + scene machinery,
VENDORED verbatim from upstream (SET_FOLDER manifest). VENDORED verbatim from upstream (SET_FOLDER manifest).
Navigation 3's runtime layers (navigation3-runtime, Navigation 3's runtime layers (navigation3-runtime,
lifecycle-viewmodel-navigation3) are real Maven KMP lifecycle-viewmodel-navigation3) are real Maven KMP
@@ -206,14 +255,37 @@ 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`, `:desktop-native-window`, …) - Module PATHS mirror the DIRECTORY 1:1 - `:compose:ui:ui`,
`settings.gradle.kts` redirects `projectDir` for each so build files across `:compose:foundation:foundation`, `:compose:desktop:native:desktop-native-window`,
the repo stay terse. `androidx.collection` is a plain Maven dependency `:sdl:sdl-core`, `:utils:material-symbols`, `:navigation3:navigation3-ui`,
`:components:resources:components-resources`. There is NO `projectDir` redirection in
`settings.gradle.kts`; a plain `include(...)` per module is the whole story, and
the intermediate container projects (`:compose`, `:compose:ui`, …) hold no code.
**INVARIANT: the leaf directory IS the published artifactId.** Don't break it to
mirror an upstream directory name. KMP derives every target publication's
coordinate as `<project.name>-<target>`, and a target DISABLED on the building
host (all Apple targets on Windows/Linux) has no publication object to retarget
afterwards - while the root `kotlinMultiplatform` metadata, which the WINDOWS
publish job owns, still emits an `available-at` for it. A mismatched leaf
therefore ships a root module pointing at a nonexistent `<leaf>-macosarm64`,
breaking macOS consumers, and no `artifactId = …` override can reach it. Two
directories are renamed away from upstream's layout to hold this:
`compose/desktop/native/desktop-native-window` (upstream: `window`) and
`components/resources/components-resources` (upstream: `library` + a hand-set
artifactId). `scripts/compose-coverage.py`'s `kTargets` carries the
upstream→local mapping for the latter.
`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
androidx KMP libs. androidx KMP libs.
## Dependency graph ## Dependency graph
Written with LEAF names for readability (`:ui` = `:compose:ui:ui`,
`:foundation` = `:compose:foundation:foundation`, …); build files use the full
path shown in the module layout above.
``` ```
:ui ← :animation-core ← :animation ← :foundation ← :material3 ← :demo, :apidemo :ui ← :animation-core ← :animation ← :foundation ← :material3 ← :demo, :apidemo
:ui ← :foundation-layout ←──────────────────────┘ ↑ ↑ :ui ← :foundation-layout ←──────────────────────┘ ↑ ↑
@@ -312,8 +384,17 @@ Two categories of code live in each module:
// VENDOR-BASE(COMPOSE_REF): <path> @ <tag> ← for umbrella-repo files // VENDOR-BASE(COMPOSE_REF): <path> @ <tag> ← for umbrella-repo files
``` ```
`scripts/compose-fork/check-vendor-drift.py` reads these at every ref A file that is a fresh REIMPLEMENTATION rather than a derived copy (same
bump: it flags any file whose recorded base lags the current pin and package + signatures, different body - see the fallback rule at the end of
this section) gets `// VENDOR-REIMPL: <path> @ <tag>` instead. That marks it
as deliberately NOT drift-tracked: upstream edits to the counterpart need no
reconciling, only a SIGNATURE change does.
`scripts/compose-fork/audit-exclusions.py` classifies every `!` exclusion as
manual vendor / reimpl / orphan and FAILS on any local counterpart carrying
neither marker, so nothing rots invisibly.
`scripts/compose-fork/check-vendor-drift.py` reads the VENDOR-BASE lines at
every ref bump: it flags any file whose recorded base lags the current pin and
(with the local clone) reports whether the upstream base ACTUALLY (with the local clone) reports whether the upstream base ACTUALLY
changed base..pin - i.e. whether the copy needs hand-reconciling or changed base..pin - i.e. whether the copy needs hand-reconciling or
just a ref re-stamp. Now it's a project file - the next sync won't just a ref re-stamp. Now it's a project file - the next sync won't
@@ -414,8 +495,8 @@ 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 (com.bitsycore.skiko:skiko: # Links the bitsycore skiko FORK from maven.bitsycore.com (com.bitsycore.skiko:skiko:
# 0.150.1-mingw.1, override -PskikoMingwVersion); the bridge plugin drops # 0.150.1-mingw.2, 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
gradlew.bat :apidemo:runDebugExecutableMingwX64 gradlew.bat :apidemo:runDebugExecutableMingwX64
@@ -472,8 +553,12 @@ executable, loaded via `SDL_GetBasePath()`). Contents:
scripts/compose-fork/sync.sh scripts/compose-fork/sync.sh
``` ```
Upstream ref: `scripts/compose-fork/compose.properties` - set to a durable tag Upstream refs live in `scripts/compose-fork/compose.properties`, one `NAME=value`
of `JetBrains/compose-multiplatform-core`. Bump the ref → re-sync → let the per repo, each pinned to a durable TAG. Five repos are vendored now:
`COMPOSE_CORE_REF` (JetBrains/compose-multiplatform-core), `COMPOSE_REF` (the
compose-multiplatform umbrella), `KOIN_REF` (InsertKoinIO/koin), `COIL_REF`
(coil-kt/coil) and `PULSE_REF` (bitsycore/pulse-mvi). Each gets its own sibling
sparse clone (`../cmp-ref`, `../cmp-ref-koin`, …). Bump the ref → re-sync → let the
build tell you what broke. Per-module sync, manifest re-formatting, and the build tell you what broke. Per-module sync, manifest re-formatting, and the
drift / vendor-clean guardrails are in drift / vendor-clean guardrails are in
[TOOLING.md](TOOLING.md#vendoring-upstream-compose). [TOOLING.md](TOOLING.md#vendoring-upstream-compose).
@@ -481,7 +566,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/desktop/native/window/src/nativeMain/…/ComposeWindow.kt` - main loop, - `compose/desktop/native/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
@@ -640,8 +725,24 @@ Verified in-tree (api-exposed by `:ui` unless noted):
- `androidx.navigationevent:navigationevent-compose` 1.1.2 - predictive-back - `androidx.navigationevent:navigationevent-compose` 1.1.2 - predictive-back
event plumbing (BackHandler, NavDisplay gestures). event plumbing (BackHandler, NavDisplay gestures).
- `androidx.collection:collection` - plain Maven dep, not a module. - `androidx.collection:collection` - plain Maven dep, not a module.
- `io.insert-koin:koin-core` **4.2.2** - the DI container itself publishes
mingwX64 + linux + macos. Only Koin's viewmodel / compose layers stop at
apple+android and are vendored (`koin/`).
- `androidx.navigationevent:navigationevent-compose` 1.1.2 AND the jetbrains
`org.jetbrains.androidx.navigationevent:navigationevent-compose` 1.1.0 - BOTH
publish mingwX64 + linux + macos. Nothing to vendor here.
- NOT compatible (vendored instead): `components-resources` (no mingw/linux - NOT compatible (vendored instead): `components-resources` (no mingw/linux
klibs → `:components-resources`), `navigation3-ui` (same → `:navigation3-ui`). klibs → `:components:resources:components-resources`), `navigation3-ui` (same →
`:navigation3:navigation3-ui`), Koin's viewmodel/compose modules (→ `koin/`),
the whole Coil 3 stack (no mingwX64 anywhere; no desktop native at all for its
compose layer → `coil/`), and Pulse MVI (no desktop native → `pulse/`).
- **Always check BOTH coordinate sets before concluding an artifact has no
desktop-native klibs.** `androidx.*` and `org.jetbrains.androidx.*` are
different artifacts with the same classes; sometimes only one carries the K/N
variant, and where both do, pick ONE - putting both on the path duplicates
every class. This port standardises on the GOOGLE `androidx.lifecycle:*`
coordinates, so vendored upstream code that referenced the jetbrains mirrors
is repointed at the google ones in the module's build file.
- Infra: `kotlinx-coroutines-core`, `atomicfu`, `okio`, - Infra: `kotlinx-coroutines-core`, `atomicfu`, `okio`,
`kotlinx-serialization`. `kotlinx-serialization`.
+151 -3
View File
@@ -103,7 +103,7 @@ gradlew :apidemo:run :: JVM apidemo reference
``` ```
- The bridge plugin auto-drops `skiko-windows-x64.dll` next to the exe (`installWindowsSkiaDll`). - The bridge plugin auto-drops `skiko-windows-x64.dll` next to the exe (`installWindowsSkiaDll`).
Fork coords `com.bitsycore.skiko:skiko:0.150.1-mingw.1` (override `-PskikoMingwVersion`). Fork coords `com.bitsycore.skiko:skiko:0.150.1-mingw.2` (override `-PskikoMingwVersion`).
- `:demo` CLI flags (native AND jvm): `--screen=<Name>`, `--screenshot=<path.bmp>` (capture at - `:demo` CLI flags (native AND jvm): `--screen=<Name>`, `--screenshot=<path.bmp>` (capture at
quiescence then quit), `--gpu=auto|software|skia.opengl`. `CDN_TEXT_METRICS=1` env var dumps quiescence then quit), `--gpu=auto|software|skia.opengl`. `CDN_TEXT_METRICS=1` env var dumps
text metrics (§1b). `CDN_PROFILE=1` frame profiler. `:apidemo` has NO screenshot CLI - drive it text metrics (§1b). `CDN_PROFILE=1` frame profiler. `:apidemo` has NO screenshot CLI - drive it
@@ -172,7 +172,7 @@ All Windows divergences live **below Kotlin** - the mingw source set reuses
the only mingw-unique file is `PlatformGpu.mingw.kt` (13 lines, GPU only). So every the only mingw-unique file is `PlatformGpu.mingw.kt` (13 lines, GPU only). So every
divergence is in the **fork's Skia binary**, in **`FontMgr.default`'s per-OS impl**, or in divergence is in the **fork's Skia binary**, in **`FontMgr.default`'s per-OS impl**, or in
the **GPU backend**. The fork is external (`bitsycore/skiko`, the **GPU backend**. The fork is external (`bitsycore/skiko`,
`com.bitsycore.skiko:skiko:0.150.1-mingw.1`) and its GN args are **not verifiable from this `com.bitsycore.skiko:skiko:0.150.1-mingw.2`) and its GN args are **not verifiable from this
tree** - recovering them is a prerequisite for several fixes below. tree** - recovering them is a prerequisite for several fixes below.
**Fidelity reference for Windows is skiko-on-JVM Compose Desktop on Windows** (also **Fidelity reference for Windows is skiko-on-JVM Compose Desktop on Windows** (also
@@ -371,7 +371,7 @@ macOS↔Windows delta is expected upstream behavior.
different ascent/descent on Windows (different metric-table selection) AND why fork different ascent/descent on Windows (different metric-table selection) AND why fork
`FontMgr.default` may not enumerate Windows system fonts for glyph fallback (FreeType `FontMgr.default` may not enumerate Windows system fonts for glyph fallback (FreeType
has no system fontmgr without fontconfig). **CAVEAT:** that's the *recommended recipe*, has no system fontmgr without fontconfig). **CAVEAT:** that's the *recommended recipe*,
not a verified dump of the shipped `0.150.1-mingw.1` GN args. **REMAINING:** whoever not a verified dump of the shipped `0.150.1-mingw.2` GN args. **REMAINING:** whoever
rebuilds the fork should capture the real `args.gn` (`SK_GAMMA_*`, ICU packaging, rebuilds the fork should capture the real `args.gn` (`SK_GAMMA_*`, ICU packaging,
freetype-vs-dwrite) alongside the fork sources so drift is auditable - NOT as a doc in freetype-vs-dwrite) alongside the fork sources so drift is auditable - NOT as a doc in
this repo (kept lean); a comment in the fork repo or `build-sdl.properties`-style pin. this repo (kept lean); a comment in the fork repo or `build-sdl.properties`-style pin.
@@ -734,3 +734,151 @@ scope for desktop 1.0 - but ship the non-throwing `PlatformScreenReader` no-op),
hand-rolled text engine as an architectural deviation (§2 P1), per-focus hand-rolled text engine as an architectural deviation (§2 P1), per-focus
`SDL_StartTextInput/StopTextInput`, `loadImageBitmap`/`loadSvgPainter` (JVM `InputStream` `SDL_StartTextInput/StopTextInput`, `loadImageBitmap`/`loadSvgPainter` (JVM `InputStream`
signatures, N/A on K/N). signatures, N/A on K/N).
## 7. Post-1.12.0 open items (opened 2026-09-12)
### 7a. JVM parity reference used a DIFFERENT default font than native - ✅ FIXED
Symptom (apidemo, `SourceTag` in `InheritanceUi.kt`): the "Session" / "Pack" pill is
`Box(padding(horizontal = 5.dp, vertical = 1.dp)) { Text(fontSize = 9.sp) }` - no explicit
vertical centering, so the pill's look is entirely decided by where the glyphs sit inside the
Text node's measured paragraph box. On the JVM leg the label looks vertically centred in the
pill; on native it does not.
**Not a centering bug - a font-resolution divergence.** The two stacks render that label in
two different typefaces, which have different ascent / descent / line-gap, so the glyph run
sits at a different height inside an equally-tall box:
- NATIVE: `FontFamily.Default` resolves to the BUNDLED **NotoSans** -
`SkiaFonts.defaultTypeface` (`compose/ui/ui-text/src/skikoRendererMain/.../SkiaFonts.kt`)
loads `font/NotoSans.ttf` from data.kres and registers it as "the fallback for every
unresolved family".
- JVM: nothing registers NotoSans as the default. `apidemo/src/jvmMain/kotlin/Fonts.jvm.kt`
only defines `monoFontFamily`; `jvmProcessResources` stages the .ttf on the classpath but
never installs it. So `FontFamily.Default` is Skiko's SYSTEM default (Segoe UI on Windows).
This is a defect in the PARITY HARNESS, not (necessarily) in the renderer: every `Text` that
doesn't name a `fontFamily` is being compared against a different typeface, so any such
difference is uninterpretable. It likely masks or manufactures other "port bugs".
**Fixed** by giving apidemo a `defaultFontFamily` expect/actual (`Fonts.kt`) that loads the
bundled `font/NotoSans.ttf` on BOTH legs - native through `IconFont.register` +
`namedFontFamily`, jvm from the classpath copy `jvmProcessResources` already stages - and
stamping it across the M3 `Typography` (`withDefaultFontFamily`), since typography styles
carry their own `fontFamily` and overriding `LocalTextStyle` alone would not reach them.
This is the SAME treatment `:demo`'s parity leg already had (see the `notoSans` /
`notoTypography` block in `demo/src/jvmMain/kotlin/MainJvm.kt`, commented "so the parity %
measures real divergence, not 'different default typeface'"). apidemo had simply never been
given it. Verified: the SourceTag pill is now vertically centred on both stacks.
### 7a-bis. apidemo drift check is now mechanised - and two residuals found
`:apidemo` had no way to capture itself, so drift could only be eyeballed. Both legs now take
`--screenshot=<path>`:
apidemo.exe --screenshot=out.bmp # native: GPU readback
./gradlew :apidemo:run --args=--screenshot=out.png # jvm: ImageComposeScene
Both render OFFSCREEN to quiescence (virtual 60fps clock, infinite animations frozen via
upstream's `InfiniteAnimationPolicy`, capture after 3 quiet frames), mirroring `:demo`'s
parity path. Neither needs a visible window, so the capture is immune to occlusion - a
screen-scrape approach was tried first and grabbed whatever happened to be in front.
First run after the font fix, 1240x820: **2.9% of pixels differ at all, 2.1% by >32/255.**
Two residuals, neither a text-metrics bug:
- **Inherited lineHeight leading distribution - ✅ FIXED.** The port never forwarded
`topRatio` to skiko. Upstream's `ParagraphBuilder.skiko.kt` sets `res.topRatio = topRatio`
on EVERY SkTextStyle, sourced from `LineHeightStyle.Alignment.topRatio`; the port set
`ts.height` and `heightMode` but left `topRatio` alone, so skiko fell back to its own
default (-1 = split the extra leading proportionally to the font's ascent:descent). For a
line box much taller than the glyphs that pushes them visibly DOWN - while Material 3's
type styles ask for `Alignment.Center` (topRatio 0.5).
One line in `SkiaParagraphEngine.kt`'s SkTextStyle builder, with `Alignment.Proportional`
as the fallback exactly like upstream, so text specifying no lineHeightStyle is unchanged.
`topRatio` is present on both the official skiko and the bitsycore mingw fork.
Measured on apidemo (1240x820), whole window, native vs jvm:
| | differ | >32/255 |
|--------------------|--------|---------|
| before | 2.94% | 2.14% |
| after | 1.52% | 0.29% |
The Session/Pack pills are now pixel-identical. This ALSO killed the "constant ~2px
vertical offset" logged alongside it - that was the same bug compounding through stacked
text rows, not an independent issue: shifting the jvm capture now makes the match WORSE
(0.29% at +0px vs 2.13% at +1px), where before +2px halved the error. The residual 0.29%
is rasterizer AA.
- **Missing glyph in the session header.** The leading icon next to "Untitled session"
renders as a `.notdef` TOFU on jvm and as NOTHING on native - so the glyph is absent from
the subsetted Material Symbols font on both, and the two stacks just disagree on how to
draw a missing glyph. The gear icon beside it is fine, so the icon-font path works; this
is almost certainly `enableIconSubsetting` missing a NON-LITERAL `MaterialSymbols.<Name>`
reference that `findMaterialSymbolsUsage` cannot see. Check that call site, and consider
making the native side draw .notdef too so a missing glyph is never silent.
### 7b. Vendor Koin + Coil3 + Pulse MVI (requested 2026-09-12) - ✅ DONE
Target-availability audit against Maven Central (the deciding fact - re-check on every
version bump, and check BOTH the google and jetbrains coordinate sets before concluding an
artifact "has no desktop klibs"):
| Artifact | mingwX64 | linuxX64/arm64 | macosArm64 | Action |
|---|---|---|---|---|
| `androidx.navigationevent:navigationevent-compose` 1.1.2 | YES | YES | YES | **none - already used as-is** |
| `org.jetbrains.androidx.navigationevent:navigationevent-compose` 1.1.0 | YES | YES | YES | **none** |
| `io.insert-koin:koin-core` 4.2.2 | YES | YES | YES | none - Maven as-is |
| `io.insert-koin:koin-core-viewmodel` 4.2.2 | no | no | YES | VENDOR |
| `io.insert-koin:koin-compose` 4.2.2 | no | no | YES | VENDOR |
| `io.insert-koin:koin-compose-viewmodel` 4.2.2 | no | no | YES | VENDOR |
| `io.insert-koin:koin-compose-viewmodel-navigation` 4.2.2 | no | no | YES | VENDOR |
| `io.coil-kt.coil3:coil-core` 3.6.2 | no | YES | YES | VENDOR (mingw gap) |
| `io.coil-kt.coil3:coil` 3.6.2 | no | YES | YES | VENDOR (mingw gap) |
| `io.coil-kt.coil3:coil-network-core` 3.6.2 | no | YES | YES | VENDOR (mingw gap) |
| `io.coil-kt.coil3:coil-network-ktor3` 3.6.2 | no | YES | YES | VENDOR (mingw gap) |
| `io.coil-kt.coil3:coil-svg` 3.6.2 | no | YES | YES | VENDOR (mingw gap) |
| `io.coil-kt.coil3:coil-compose-core` 3.6.2 | no | no | YES | VENDOR |
| `io.coil-kt.coil3:coil-compose` 3.6.2 | no | no | YES | VENDOR |
NOTE the original premise that navigationevent-compose lacks desktop-native artifacts is
WRONG - both coordinate sets publish mingwX64 + linux + macos, and the port already consumes
`androidx.navigationevent:navigationevent-compose:1.1.2` unmodified ("Known Compatible" in
CLAUDE.md, exercised by `demo --backtest`). Nothing to vendor there.
**Landed** as `koin/` (4 modules, `com.bitsycore.koin`), `coil/` (7 modules,
`com.bitsycore.coil3`) and `pulse/` (4 modules, `com.bitsycore.pulse`) - 202 files vendored
verbatim across three new pinned repos (`KOIN_REF=4.2.2`, `COIL_REF=3.6.2`,
`PULSE_REF=0.3.7`), ZERO local source edits. All build for mingwX64 + linuxX64/arm64, are
BCV-dumped, publish, and carry bridge substitution rules so consumers keep declaring the
official coordinates.
Three things worth remembering from doing it:
- **nav2 is a dead end here.** koin-compose-viewmodel-navigation needs nav2's
`navigation-compose`, which has no mingwX64/linux klibs under either coordinate set.
Vendored `koin-compose-navigation3` instead - it needs only koin-compose +
navigation3-runtime, matching this port's nav3 story.
- **Upstream `non*` source sets must stay ABOVE nativeMain, not merge into it.** Several
declare `expect`s whose `actual`s live in upstream nativeMain; collapsing both into one
source set makes them siblings, which is a hard error.
- **A shared-metadata compilation is a real compile.** Coil's nonAndroid code uses
`org.jetbrains.skia.*` directly, so the INTERMEDIATE source set holding it needs skiko on
its own classpath - and since mingwX64 needs the FORK while macOS/Linux need the official
build, the two cannot share an intermediate. coil-core / coil-svg / coil-compose-core
therefore carry two PARALLEL branches over the same srcDirs, the shape
:compose:ui:ui-graphics already used. Kotlin emits no metadata compilation for the
single-target fork branch, so they never collide.
Also hit the granular-metadata trap (CLAUDE.md "Common pitfalls") in coil-compose-core:
every artifact the shared code touches must be declared DIRECTLY and get its own bridge
rule, or `compileCommonMainKotlinMetadata` loses its transitives on the Windows publish job.
REMAINING (deliberate): upstream Koin/Coil/Pulse reference the
`org.jetbrains.androidx.lifecycle:*` mirrors while this port standardises on the GOOGLE
`androidx.lifecycle:*` coords. The build files repoint them, but a consumer that pulls the
jetbrains mirrors in itself will get duplicate `unique_name` klib warnings at metadata
compile. Harmless today; if it ever becomes an error, force the google coords repo-wide.
+124 -20
View File
@@ -1,4 +1,4 @@
[![Kotlin](https://img.shields.io/badge/Kotlin-2.4.0-blue.svg?style=flat&logo=kotlin)](https://kotlinlang.org) [![Kotlin](https://img.shields.io/badge/Kotlin-2.4.20-blue.svg?style=flat&logo=kotlin)](https://kotlinlang.org)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE.md) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE.md)
# Compose Desktop Native # Compose Desktop Native
@@ -18,6 +18,9 @@ executable for macOS (arm64), Linux (x64/arm64), and Windows (mingwX64), using
- **The UI layers are vendored upstream.** `androidx.compose.ui`, `foundation`, - **The UI layers are vendored upstream.** `androidx.compose.ui`, `foundation`,
`animation`, and `material3` are copied from Compose Multiplatform verbatim `animation`, and `material3` are copied from Compose Multiplatform verbatim
wherever they compile as is, with project code filling in only the native glue. wherever they compile as is, with project code filling in only the native glue.
The same treatment extends to ecosystem libraries that stop short of
Kotlin/Native desktop - Koin, Coil 3 and Pulse MVI are vendored and rebuilt for
these targets, and you still declare their official coordinates.
- **Rendering is Skia everywhere.** macOS and Linux link the official Skiko - **Rendering is Skia everywhere.** macOS and Linux link the official Skiko
klibs (Metal / OpenGL); Windows links the bitsycore Skiko fork, which ships klibs (Metal / OpenGL); Windows links the bitsycore Skiko fork, which ships
Skiko and Skia together in `skiko-windows-x64.dll`. Skiko and Skia together in `skiko-windows-x64.dll`.
@@ -72,9 +75,9 @@ saved state behave as they do on Android.
```kotlin ```kotlin
commonMain.dependencies { commonMain.dependencies {
implementation(project(":desktop-native-window")) // window shell + main loop implementation(project(":compose:desktop:native:desktop-native-window")) // window shell + main loop
implementation(project(":material3")) // Material 3 widgets implementation(project(":compose:material3:material3")) // Material 3 widgets
implementation(project(":material-symbols")) // icon-font composables (optional) implementation(project(":utils:material-symbols")) // icon-font composables (optional)
} }
``` ```
@@ -106,15 +109,11 @@ commonMain.dependencies {
} }
``` ```
**Two GitHub Packages repos are needed.** A consumer declares the port's repo **One repository, no credentials.** `https://maven.bitsycore.com/releases`
(`bitsycore/compose-desktop-native`) **and** the skiko fork's (`bitsycore/skiko`). carries both the port's artifacts and the bitsycore skiko fork
The Windows (mingwX64) target renders through the bitsycore skiko fork, and (`com.bitsycore.skiko`), which the Windows (mingwX64) target renders through;
GitHub Packages binds each package name to a **single** repository - so macOS/Linux pull the official skiko from Maven Central instead. The exact
`com.bitsycore.skiko` can't be mirrored into the port's repo, it stays in its `repositories {}` snippet and version pinning:
own. Scope them with `includeGroup`/`excludeGroup("com.bitsycore.skiko")`
(macOS/Linux pull the official skiko from Maven Central instead; if you build no
mingwX64 you can omit the fork repo). The exact `repositories {}` snippet,
credentials, and version pinning:
[gradle-plugin/compose-desktop-native-bridge/README.md](gradle-plugin/compose-desktop-native-bridge/README.md). [gradle-plugin/compose-desktop-native-bridge/README.md](gradle-plugin/compose-desktop-native-bridge/README.md).
For a complete project that applies the bridge and builds one shared UI for For a complete project that applies the bridge and builds one shared UI for
@@ -152,16 +151,121 @@ client certificates.
## Modules ## Modules
One Gradle module per upstream Compose artifact, mirroring the upstream One Gradle module per upstream artifact, and the Gradle path mirrors the
`compose/` tree. The renderer lives in `:ui` and the `sdl3` cinterop in directory (`:compose:ui:ui`, `:compose:foundation:foundation`, …). The renderer
`:sdl-core`; `:desktop-native-window` is the SDL integration layer. `:material-symbols`, `:components-resources`, and lives in `:compose:ui:ui` and the `sdl3` cinterop in `:sdl:sdl-core`;
`:navigation3-ui` are project or vendored modules that the official Maven `:compose:desktop:native:desktop-native-window` is the SDL integration layer.
artifacts do not cover for Kotlin/Native desktop.
Most of the androidx architecture stack (lifecycle, viewmodel, navigation3, Most of the androidx architecture stack (lifecycle, viewmodel, navigation3,
savedstate, navigationevent) ships real Kotlin/Native desktop klibs and runs on savedstate, navigationevent) ships real Kotlin/Native desktop klibs and runs on
the port unmodified. The full module map, dependency graph, and the list of the port unmodified. Where an ecosystem library stops short of Kotlin/Native
compatible artifacts are in [CLAUDE.md](CLAUDE.md). desktop, this repo vendors it verbatim from upstream and rebuilds it for these
targets, so you keep writing against the official coordinates:
| Vendored | Why | Published as |
|----------|-----|--------------|
| Compose `ui` / `foundation` / `animation` / `material3` | the port itself | `com.bitsycore.compose.*` |
| `components-resources`, `navigation3-ui` | no mingwX64 / linux klibs | `com.bitsycore.compose.components`, `com.bitsycore.navigation3` |
| **Koin** viewmodel + compose modules | apple + android only upstream (`koin-core` itself is fine) | `com.bitsycore.koin` |
| **Coil 3** (whole stack) | no mingwX64 anywhere; no desktop native at all for its compose layer | `com.bitsycore.coil3` |
| **Pulse MVI** | no desktop-native artifact upstream | `com.bitsycore.pulse` |
The bridge plugin substitutes each of these on native desktop configurations, so
app code declares `io.insert-koin:koin-compose`, `io.coil-kt.coil3:coil-compose`
and so on exactly as it would anywhere else. The full module map, dependency
graph, and the list of compatible artifacts are in [CLAUDE.md](CLAUDE.md).
## Pinned versions
Everything below is pinned in exactly two files -
[`gradle/libs.versions.toml`](gradle/libs.versions.toml) (Maven coordinates) and
[`scripts/compose-fork/compose.properties`](scripts/compose-fork/compose.properties)
(the upstream git refs the vendored sources are copied from) - plus
[`scripts/build-sdl/build-sdl.properties`](scripts/build-sdl/build-sdl.properties)
for SDL3. A release tracks one Compose Multiplatform version; the table is the
contract.
**Version policy.** Anything Compose Multiplatform integrates is pinned to what
CMP ships - for the androidx mirrors, the *Jetpack* version CMP's release notes
map its `org.jetbrains.androidx.*` artifact to, since this port consumes the
google coordinates. Anything CMP does not integrate is pinned to the latest
release. Deliberate exceptions are commented in the catalog; there is currently
one (`savedstate`, below).
### Toolchain
| | Version | Notes |
|---|---|---|
| Kotlin | **2.4.20** | Newer than the 2.3.20 CMP 1.12.0 is built with. Kotlin/Native consumes older klibs fine, and the whole port builds clean on 2.4.20 with no klib API diff, so there is no reason to hold back. |
| Compose Multiplatform | **1.12.0** | The vendored sources are the `v1.12.0` tag of both upstream repos, and the JVM parity leg forces the same version - no dev-build skew. |
| SDL3 | **release-3.4.16** | Built from source as a static lib per host (`scripts/build-sdl/build-all.py`), linked into the executable. |
| Skiko | **0.150.1** | macOS / Linux use the official `org.jetbrains.skiko`. |
| Skiko (Windows fork) | **0.150.1-mingw.2** | `com.bitsycore.skiko:skiko` - Skiko + Skia in `skiko-windows-x64.dll`. Same Skia base as the official build. Public repo, no auth. |
### Compose libraries
The port republishes each vendored artifact under a `com.bitsycore` group that
mirrors the upstream one, so the fork of any given coordinate is obvious. Apply
the bridge plugin and you keep declaring the **official** coordinate.
| Library | Official coordinate | Port coordinate |
|---|---|---|
| Runtime | `org.jetbrains.compose.runtime:runtime*:1.12.0` | *not forked - the official klibs serve every target* |
| UI | `org.jetbrains.compose.ui:ui*:1.12.0` | `com.bitsycore.compose.ui:ui*` |
| Foundation | `org.jetbrains.compose.foundation:foundation*:1.12.0` | `com.bitsycore.compose.foundation:foundation*` |
| Animation | `org.jetbrains.compose.animation:animation*:1.12.0` | `com.bitsycore.compose.animation:animation*` |
| Material Ripple | `org.jetbrains.compose.material:material-ripple:1.12.0` | `com.bitsycore.compose.material:material-ripple` |
| Material3 | `org.jetbrains.compose.material3:material3:1.12.0-alpha03` | `com.bitsycore.compose.material3:material3` |
| Resources | `org.jetbrains.compose.components:components-resources:1.12.0` | `com.bitsycore.compose.components:components-resources` |
| Navigation3 UI | `org.jetbrains.androidx.navigation3:navigation3-ui` | `com.bitsycore.navigation3:navigation3-ui` |
| Window shell | *no upstream equivalent* | `com.bitsycore.compose:desktop-native-window` |
| SDL layer | *no upstream equivalent* | `com.bitsycore.compose.sdl:sdl-core` |
Material3 rides its own release train upstream: `1.12.0-alpha03` **is** the
version Compose Multiplatform 1.12.0 ships (Jetpack Material3 1.5.0-alpha22).
### Ecosystem libraries
Vendored because upstream stops short of Kotlin/Native desktop. The bridge
substitutes them on native desktop targets only.
| Library | Official coordinate | Port coordinate | Why |
|---|---|---|---|
| Koin | `io.insert-koin:koin-compose*:4.2.2` | `com.bitsycore.koin:*` | apple + android only upstream |
| Koin core | `io.insert-koin:koin-core:4.2.2` | *not forked* | already ships mingwX64 + linux |
| Coil 3 | `io.coil-kt.coil3:coil*:3.6.2` | `com.bitsycore.coil3:*` | no mingwX64 anywhere; no desktop native at all for the compose layer |
| Pulse MVI | `com.bitsycore.lib:pulse*:0.3.7` | `com.bitsycore.pulse:*` | no desktop-native artifact upstream |
Koin's `koin-compose-viewmodel-navigation` is deliberately **not** provided: it
needs Navigation 2's `navigation-compose`, which has no mingwX64 or linux klibs
under either coordinate set. Use `koin-compose-navigation3`.
### AndroidX, used as-is
These publish real Kotlin/Native desktop klibs and run on the port unmodified -
nothing is vendored or substituted. The port standardises on the **google**
`androidx.*` coordinates; do not also pull the `org.jetbrains.androidx.*`
mirrors or you will have every class twice.
| Library | Coordinate |
|---|---|
| Lifecycle / ViewModel | `androidx.lifecycle:lifecycle-*:2.11.0` |
| SavedState | `androidx.savedstate:savedstate*:1.5.0` (CMP builds against 1.4.0; lifecycle 2.11.0 requires it only as a *minimum*, so 1.5.0 resolves cleanly and gives consumers the newer API) |
| Navigation3 runtime | `androidx.navigation3:navigation3-runtime:1.2.0-alpha04` |
| Navigation Event | `androidx.navigationevent:navigationevent-compose:1.1.2` |
| Collection | `androidx.collection:collection:1.5.0` |
| Graphics Shapes | `androidx.graphics:graphics-shapes:1.1.0` |
### Infrastructure
| Library | Version |
|---|---|
| kotlinx-coroutines | 1.11.0 |
| kotlinx-serialization | 1.11.0 |
| kotlinx-datetime | 0.8.0 |
| kotlinx-io-okio | 0.9.1 |
| Okio | 3.18.2 |
| Ktor | 3.5.2 |
## Building ## Building
+26 -11
View File
@@ -48,15 +48,24 @@ Reach for this after a fresh checkout or a ref bump. Details:
Guardrails that keep the vendor tree honest: Guardrails that keep the vendor tree honest:
```bash ```bash
python3 scripts/compose-fork/check-vendor-clean.py # src/vendor matches the pinned refs python3 scripts/compose-fork/check-vendor-clean.py # src/vendor matches the pinned refs
python3 scripts/compose-fork/check-vendor-drift.py # hand-edited "manual vendors" match their pin python3 scripts/compose-fork/check-vendor-drift.py # hand-edited "manual vendors" match their pin
python3 scripts/compose-fork/audit-exclusions.py # every `!` exclusion is classified
``` ```
`check-vendor-clean` fails if a hand-edit ever leaks into `src/vendor/`. `check-vendor-clean` fails if a hand-edit ever leaks into `src/vendor/`.
`check-vendor-drift` reads the `// VENDOR-BASE:` header on every edited copy and, `check-vendor-drift` reads the `// VENDOR-BASE:` header on every edited copy and,
using the local upstream clone, reports whether the base actually changed since using the local upstream clone, reports whether the base actually changed since
the pin (needs reconciling) or is merely stale (safe to re-stamp). Run both on the pin (needs reconciling) or is merely stale (safe to re-stamp).
every ref bump.
`audit-exclusions` covers the other half: a manifest `!` line takes a file OUT of
the verbatim sync, and the local replacement is either a derived copy
(`// VENDOR-BASE:`, drift-tracked) or a fresh reimplementation
(`// VENDOR-REIMPL:`, deliberately not tracked - only a SIGNATURE change matters).
It classifies each one, flags any local counterpart carrying NEITHER marker
(invisible to the drift check, silently rotting) and any copy that has become
identical to upstream (drop it and re-vendor), and exits non-zero on an
unclassified file. Run all three on every ref bump.
### Coverage against upstream ### Coverage against upstream
@@ -160,8 +169,8 @@ 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 `com.bitsycore.skiko:skiko:0.150.1-mingw.1` (macOS/Linux use the PUBLIC `https://maven.bitsycore.com/releases` (no credentials) as
official Skiko). The runtime `skiko-windows-x64.dll` is auto-provisioned next `com.bitsycore.skiko:skiko:0.150.1-mingw.2` (macOS/Linux use 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
from this repo's release flow. from this repo's release flow.
@@ -184,8 +193,9 @@ single file to edit; know which axis you are changing.
|---------|-------|-------| |---------|-------|-------|
| 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`. | | 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. | | Vendored ecosystem libs | `KOIN_REF`, `COIL_REF`, `PULSE_REF` in the same file, plus `koin` / `coil` in `gradle/libs.versions.toml`. | Same rule: durable tags. Each repo gets its own sibling sparse clone (`../cmp-ref-koin`, `../cmp-ref-coil`, `../cmp-ref-pulse-mvi`). Re-sync, then `apiDump` - these modules are BCV-validated like the rest. |
| 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. | | JVM parity forcing | `compose` / `composeMaterial3` / `composeRuntime` in `gradle/libs.versions.toml` (read by `demo`, `apidemo`, `material-symbols` and the root build's forcing map). | Must be a version PUBLISHED to Maven Central. It may lag the vendored native ref (a documented skew) until the matching version is published; at v1.12.0 they are in lockstep. |
| Skiko | `skiko` (official) and `skikoMingw` (the fork) in `gradle/libs.versions.toml`; keep the fork's `-mingw.N` base equal to `skiko`. | macOS/Linux use official Skiko (`org.jetbrains.skiko`); mingwX64 uses the bitsycore fork (`com.bitsycore.skiko:skiko:0.150.1-mingw.2` from the public maven.bitsycore.com), 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. |
@@ -193,12 +203,17 @@ single file to edit; know which axis you are changing.
Run this on each upstream bump; it is the flow that keeps the sync tax low. Run this on each upstream bump; it is the flow that keeps the sync tax low.
1. Edit `COMPOSE_CORE_REF` / `COMPOSE_REF` in `compose.properties` (and `compose` 1. Edit the relevant `*_REF` in `compose.properties` - `COMPOSE_CORE_REF` /
in `libs.versions.toml` if the coordinate version moved). `COMPOSE_REF` for Compose, `KOIN_REF` / `COIL_REF` / `PULSE_REF` for the
ecosystem libs (and the matching entry in `libs.versions.toml` if the
coordinate version moved).
2. `scripts/compose-fork/sync.sh` 2. `scripts/compose-fork/sync.sh`
3. `python3 scripts/compose-fork/check-vendor-drift.py`. For any manual vendor 3. `python3 scripts/compose-fork/check-vendor-drift.py`. For any manual vendor
whose upstream base actually changed, reconcile by hand; otherwise re-stamp whose upstream base actually changed, reconcile by hand; otherwise re-stamp
its `// VENDOR-BASE:` header to the new ref. its `// VENDOR-BASE:` header to the new ref. Then
`python3 scripts/compose-fork/audit-exclusions.py` - a newly-identical copy
should go back to verbatim vendoring, and an unclassified one needs a marker.
Finish with `./gradlew apiDump` and review the klib API diff.
4. Build and fix any fallout. 4. Build and fix any fallout.
5. `scripts/verify-mac.sh` (green, including the soak and parity gates). 5. `scripts/verify-mac.sh` (green, including the soak and parity gates).
6. If a matching Compose version is now published to Maven, bump 6. If a matching Compose version is now published to Maven, bump
+6 -2
View File
@@ -68,7 +68,7 @@ kotlin {
implementation("org.jetbrains.compose.material3:material3:$vComposeM3JvmVersion") implementation("org.jetbrains.compose.material3:material3:$vComposeM3JvmVersion")
// Common Material Symbols Utility // Common Material Symbols Utility
implementation(project(":material-symbols")) implementation(project(":utils:material-symbols"))
implementation(libs.ktor.client.core) implementation(libs.ktor.client.core)
implementation(libs.ktor.client.content.negotiation) implementation(libs.ktor.client.content.negotiation)
@@ -81,13 +81,17 @@ kotlin {
} }
nativeMain { nativeMain {
dependencies { dependencies {
implementation(project(":desktop-native-window")) implementation(project(":compose:desktop:native:desktop-native-window"))
implementation(libs.ktor.client.curl) implementation(libs.ktor.client.curl)
} }
} }
jvmMain { jvmMain {
dependencies { dependencies {
implementation(compose.desktop.currentOs) implementation(compose.desktop.currentOs)
// decodeToImageBitmap / decodeToSvgPainter (window icon + in-memory
// image viewer). JVM-only: the native side goes through the port's
// own EncodedImageDecoder seam, so this stays out of commonMain.
implementation("org.jetbrains.compose.components:components-resources:${libs.versions.compose.get()}")
implementation(libs.ktor.client.cio) implementation(libs.ktor.client.cio)
implementation(libs.kotlinx.coroutines.swing) implementation(libs.kotlinx.coroutines.swing)
} }
+7 -1
View File
@@ -915,7 +915,13 @@ internal fun App() {
val vExtended = if (vDark) vPalette.scheme.darkExtended else vPalette.scheme.lightExtended val vExtended = if (vDark) vPalette.scheme.darkExtended else vPalette.scheme.lightExtended
val vC = appColorsFromScheme(vScheme) val vC = appColorsFromScheme(vScheme)
MaterialTheme(colorScheme = vScheme) { // PARITY: pin the default text family to the bundled NotoSans on BOTH stacks.
// Left alone, native resolves FontFamily.Default to the bundled font while the
// JVM leg resolves it to a system face, so every un-familied Text was being
// compared against a different typeface (see Fonts.kt).
val vTypography = MaterialTheme.typography.withDefaultFontFamily(defaultFontFamily)
MaterialTheme(colorScheme = vScheme, typography = vTypography) {
CompositionLocalProvider( CompositionLocalProvider(
LocalAppColors provides vC, LocalAppColors provides vC,
LocalVolticExtended provides vExtended, LocalVolticExtended provides vExtended,
+48
View File
@@ -1,5 +1,6 @@
package apidemo package apidemo
import androidx.compose.material3.Typography
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
// ================== // ==================
@@ -11,6 +12,9 @@ import androidx.compose.ui.text.font.FontFamily
// back to the default proportional font. // back to the default proportional font.
const val kMonoFamily = "noto-mono" const val kMonoFamily = "noto-mono"
/** Family name the bundled proportional font registers under. */
const val kDefaultFamily = "noto-sans"
/** The raw family name string - used by wrappedRowCount, which measures via the /** The raw family name string - used by wrappedRowCount, which measures via the
platform text pipeline (accepts a name string). Null when not bundled. */ platform text pipeline (accepts a name string). Null when not bundled. */
expect val monoFontFamilyName: String? expect val monoFontFamilyName: String?
@@ -18,3 +22,47 @@ expect val monoFontFamilyName: String?
/** The material3 Text / BasicTextField-shaped FontFamily for the mono family. /** The material3 Text / BasicTextField-shaped FontFamily for the mono family.
Null when not bundled. */ Null when not bundled. */
expect val monoFontFamily: FontFamily? expect val monoFontFamily: FontFamily?
// ==================
// MARK: Default proportional font (seam)
// ==================
// PARITY: the native side resolves FontFamily.Default to the BUNDLED NotoSans
// (SkiaFonts.defaultTypeface is the fallback for every unresolved family), while
// stock Compose Desktop on the JVM resolves it to a SYSTEM font (Segoe UI on
// Windows, Helvetica on macOS). Different typefaces mean different ascent /
// descent / line-gap, so identical layout code puts glyphs at a different height
// inside an identically-sized text box - which is what made the SourceTag pill
// look vertically centred on JVM and off-centre on native.
//
// The two stacks must rasterise the SAME face for the comparison to mean
// anything, so the app pins its default family explicitly rather than inheriting
// whatever the platform picks. Null = the bundled font isn't available, in which
// case we fall back to the platform default and the skew returns.
/** The bundled proportional font, applied app-wide as the default text family.
Null when NotoSans isn't shipped (data.kres on native, classpath font/ on jvm). */
expect val defaultFontFamily: FontFamily?
/** Re-stamps every style in a Material 3 [Typography] with [inFamily]. M3 seeds
LocalTextStyle from the typography, so this reaches every `Text` that doesn't name
a family of its own. A null family leaves the typography untouched. */
fun Typography.withDefaultFontFamily(inFamily: FontFamily?): Typography {
if (inFamily == null) return this
return copy(
displayLarge = displayLarge.copy(fontFamily = inFamily),
displayMedium = displayMedium.copy(fontFamily = inFamily),
displaySmall = displaySmall.copy(fontFamily = inFamily),
headlineLarge = headlineLarge.copy(fontFamily = inFamily),
headlineMedium = headlineMedium.copy(fontFamily = inFamily),
headlineSmall = headlineSmall.copy(fontFamily = inFamily),
titleLarge = titleLarge.copy(fontFamily = inFamily),
titleMedium = titleMedium.copy(fontFamily = inFamily),
titleSmall = titleSmall.copy(fontFamily = inFamily),
bodyLarge = bodyLarge.copy(fontFamily = inFamily),
bodyMedium = bodyMedium.copy(fontFamily = inFamily),
bodySmall = bodySmall.copy(fontFamily = inFamily),
labelLarge = labelLarge.copy(fontFamily = inFamily),
labelMedium = labelMedium.copy(fontFamily = inFamily),
labelSmall = labelSmall.copy(fontFamily = inFamily),
)
}
+12
View File
@@ -21,3 +21,15 @@ actual val monoFontFamily: FontFamily? by lazy {
actual val monoFontFamilyName: String? by lazy { actual val monoFontFamilyName: String? by lazy {
if (monoFontFamily != null) kMonoFamily else null if (monoFontFamily != null) kMonoFamily else null
} }
/** The JVM leg would otherwise inherit a SYSTEM font here; load the same bundled
NotoSans the native build uses so the two stacks are comparable. */
actual val defaultFontFamily: FontFamily? by lazy {
val vBytes = object {}.javaClass.getResourceAsStream("/font/NotoSans.ttf")?.use { it.readBytes() }
if (vBytes == null) {
println("apidemo: NotoSans.ttf not on the classpath - using the platform default font")
null
} else {
FontFamily(Font(identity = kDefaultFamily, data = vBytes))
}
}
+77 -2
View File
@@ -1,19 +1,48 @@
package apidemo package apidemo
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.ImageComposeScene
import androidx.compose.ui.graphics.painter.BitmapPainter import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.platform.InfiniteAnimationPolicy
import androidx.compose.ui.res.useResource import androidx.compose.ui.res.useResource
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState import androidx.compose.ui.window.rememberWindowState
import apidemo.compat.jvmOnCloseRequest
import apidemo.compat.jvmOnKeyShortcut
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import org.jetbrains.compose.resources.decodeToImageBitmap import org.jetbrains.compose.resources.decodeToImageBitmap
import org.jetbrains.skia.EncodedImageFormat
import java.io.File
// The JVM comparison app's entry point. Runs the SAME shared App() as the // The JVM comparison app's entry point. Runs the SAME shared App() as the
// native :apidemo, but on Compose Desktop (JVM) against upstream // native :apidemo, but on Compose Desktop (JVM) against upstream
// org.jetbrains.compose. Client-certificate (mTLS) features are native-only // org.jetbrains.compose. Client-certificate (mTLS) features are native-only
// (they drive the bundled libcurl); the jvm actuals report that instead. // (they drive the bundled libcurl); the jvm actuals report that instead.
fun main() = application { //
// --screenshot=<path.png> render headlessly to quiescence, write, exit
//
// The screenshot mode is the JVM half of the native-vs-JVM drift check; the
// native half is `apidemo.exe --screenshot=<path.bmp>`. Both render offscreen
// (ImageComposeScene here, a GPU readback there), so neither needs a visible
// window and the comparison is unaffected by whatever is on screen.
fun main(args: Array<String>) {
val screenshot = args.firstOrNull { it.startsWith("--screenshot=") }?.substringAfter('=')
if (screenshot != null) {
screenshotApp(File(screenshot), kWidth, kHeight)
return
}
runInteractive()
}
private const val kWidth = 1240
private const val kHeight = 820
private fun runInteractive() = application {
// Voltic window icon (mirrors the native window icon). Staged onto the // Voltic window icon (mirrors the native window icon). Staged onto the
// classpath at icon/ by jvmProcessResources. // classpath at icon/ by jvmProcessResources.
val vIcon = remember { val vIcon = remember {
@@ -25,8 +54,54 @@ fun main() = application {
onPreviewKeyEvent = { jvmOnKeyShortcut?.invoke(it) ?: false }, onPreviewKeyEvent = { jvmOnKeyShortcut?.invoke(it) ?: false },
title = "API Manager - JVM (upstream Compose)", title = "API Manager - JVM (upstream Compose)",
icon = vIcon, icon = vIcon,
state = rememberWindowState(width = 1240.dp, height = 820.dp), state = rememberWindowState(width = kWidth.dp, height = kHeight.dp),
) { ) {
App() App()
} }
} }
// ==================
// MARK: Headless screenshot (drift check vs the native leg)
// ==================
private const val kFrameNanos = 16_666_667L
private const val kMaxFrames = 300
/** Infinite animations would never let the scene go quiet; upstream's test policy
freezes them at their initial value (same trick :demo's parity leg uses). */
private object CancelInfiniteAnimations : InfiniteAnimationPolicy {
override suspend fun <R> onInfiniteOperation(block: suspend () -> R): R =
throw CancellationException("infinite animations disabled for the drift screenshot")
}
/** Render [App] offscreen at density 1 - matching the native leg, which lays out in
physical pixels - stepping a virtual 60fps clock until the scene stops invalidating. */
@OptIn(ExperimentalComposeUiApi::class)
private fun screenshotApp(outFile: File, width: Int, height: Int) {
outFile.parentFile?.mkdirs()
val scene = ImageComposeScene(
width, height, density = Density(1f),
coroutineContext = Dispatchers.Unconfined + CancelInfiniteAnimations,
) {
App()
}
try {
var nanos = 0L
var frames = 0
var image = scene.render(nanos)
while (scene.hasInvalidations() && frames < kMaxFrames) {
nanos += kFrameNanos
image = scene.render(nanos)
frames++
}
val png = image.encodeToData(EncodedImageFormat.PNG)
if (png == null) {
println("jvm screenshot: PNG encode failed")
return
}
outFile.writeBytes(png.bytes)
println("jvm screenshot: ${outFile.path} (settled after $frames frame(s))")
} finally {
scene.close()
}
}
@@ -19,6 +19,7 @@ import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import apidemo.monoFontFamily
import org.jetbrains.compose.resources.decodeToSvgPainter import org.jetbrains.compose.resources.decodeToSvgPainter
import org.jetbrains.skia.Image import org.jetbrains.skia.Image
import java.awt.Desktop import java.awt.Desktop
+13
View File
@@ -23,3 +23,16 @@ actual val monoFontFamilyName: String? by lazy {
actual val monoFontFamily: FontFamily? by lazy { actual val monoFontFamily: FontFamily? by lazy {
monoFontFamilyName?.let { namedFontFamily(it) } monoFontFamilyName?.let { namedFontFamily(it) }
} }
/** Native already resolves FontFamily.Default to the bundled NotoSans, but the
family is registered by name so both stacks go through the same lookup. */
actual val defaultFontFamily: FontFamily? by lazy {
val vBytes = loadComposeResourceBytes("font/NotoSans.ttf")
if (vBytes == null) {
println("apidemo: NotoSans.ttf not bundled - using the platform default font")
null
} else {
IconFont.register(kDefaultFamily, vBytes)
namedFontFamily(kDefaultFamily)
}
}
+59 -2
View File
@@ -1,7 +1,13 @@
package apidemo package apidemo
import com.compose.sdl.AppWindowIcon import com.compose.sdl.AppWindowIcon
import com.compose.sdl.disableInfiniteAnimations
import com.compose.sdl.nativeComposeWindow import com.compose.sdl.nativeComposeWindow
import com.compose.sdl.useVirtualFrameTime
import com.compose.sdl.windowHasInvalidations
import kotlinx.cinterop.ExperimentalForeignApi
import utils.encodeBmpBgra32
import utils.writeFile
// ================== // ==================
// MARK: Entry point (native - SDL window shell) // MARK: Entry point (native - SDL window shell)
@@ -15,6 +21,57 @@ private val kAppIcon = AppWindowIcon(
dark = listOf("icon/voltic-icon-dark-128.rgba", "icon/voltic-icon-dark-32.rgba") dark = listOf("icon/voltic-icon-dark-128.rgba", "icon/voltic-icon-dark-32.rgba")
) )
fun main() { private const val kWidth = 1240
nativeComposeWindow(title = "API Manager", width = 1240, height = 820, icon = kAppIcon) { App() } private const val kHeight = 820
/** Safety net for content that never stops invalidating. */
private const val kMaxFrames = 300
/**
* Entry point.
*
* `--screenshot=<path.bmp>` renders to quiescence and dumps the framebuffer, then
* exits - the native half of the JVM-vs-native drift check (the JVM half is
* `./gradlew :apidemo:run --args=--screenshot=<path.png>`, which goes through
* ImageComposeScene). The capture is a GPU READBACK, not a screen grab, so it
* does not care whether the window is visible or occluded.
*/
@OptIn(ExperimentalForeignApi::class)
fun main(args: Array<String>) {
val screenshot = args.firstOrNull { it.startsWith("--screenshot=") }?.substringAfter('=')
if (screenshot != null) {
// Match the JVM leg: freeze infinite animations and drive a virtual clock so
// entrance animations settle deterministically instead of run-to-run.
disableInfiniteAnimations = true
useVirtualFrameTime = true
}
nativeComposeWindow(
title = "API Manager",
width = kWidth,
height = kHeight,
icon = kAppIcon,
onFrame = if (screenshot != null) {
// Capture once the window reports no pending invalidations for a few
// consecutive frames, or at the cap. Mirrors :demo's parity path.
var quietFrames = 0
{ backend, frameIndex ->
quietFrames = if (windowHasInvalidations()) 0 else quietFrames + 1
if (quietFrames >= 3 || frameIndex >= kMaxFrames) {
if (frameIndex >= kMaxFrames) {
println("Screenshot: quiescence not reached by frame $frameIndex - capturing anyway")
}
val snap = backend.snapshotBgra()
if (snap != null) {
val (w, h, bgra) = snap
writeFile(screenshot, encodeBmpBgra32(w, h, bgra))
println("Wrote screenshot: $screenshot (${w}x$h, settled at frame $frameIndex)")
} else {
println("Screenshot snapshot was null")
}
false // quit
} else true
}
} else null,
) { App() }
} }
@@ -0,0 +1,83 @@
package utils
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.refTo
import platform.posix.fclose
import platform.posix.fopen
import platform.posix.fwrite
// ==================
// MARK: BMP save
// ==================
// Copy of demo/src/nativeMain/kotlin/utils/Bmp.kt. Kept duplicated rather than
// promoted into a library module: it is app-level tooling for the drift-check
// screenshots, and :ui-graphics deliberately does not re-export skiko to apps,
// so there is no natural shared home that would not widen the published API.
// ==================
@OptIn(ExperimentalForeignApi::class)
internal fun writeFile(inPath: String, inBytes: ByteArray) {
val vFile = fopen(inPath, "wb") ?: run {
println("fopen failed for $inPath")
return
}
fwrite(inBytes.refTo(0), 1u, inBytes.size.toULong(), vFile)
fclose(vFile)
}
/** Minimal BMP writer: 24-bit BGR (drop alpha) with the classic 40-byte
BITMAPINFOHEADER. Universally readable, including `sips`. Rows are
bottom-up (positive height) and padded to 4 bytes. */
internal fun encodeBmpBgra32(inWidth: Int, inHeight: Int, inBgra: ByteArray): ByteArray {
val kFileHeader = 14
val kInfoHeader = 40
val vRowBytes = inWidth * 3
val vRowPad = (4 - vRowBytes % 4) % 4
val vStride = vRowBytes + vRowPad
val vPixelBytes = vStride * inHeight
val vTotal = kFileHeader + kInfoHeader + vPixelBytes
val vOut = ByteArray(vTotal)
fun putU16LE(off: Int, v: Int) {
vOut[off] = (v and 0xFF).toByte()
vOut[off + 1] = ((v ushr 8) and 0xFF).toByte()
}
fun putU32LE(off: Int, v: Int) {
vOut[off] = (v and 0xFF).toByte()
vOut[off + 1] = ((v ushr 8) and 0xFF).toByte()
vOut[off + 2] = ((v ushr 16) and 0xFF).toByte()
vOut[off + 3] = ((v ushr 24) and 0xFF).toByte()
}
// BITMAPFILEHEADER
vOut[0] = 'B'.code.toByte(); vOut[1] = 'M'.code.toByte()
putU32LE(2, vTotal)
putU32LE(10, kFileHeader + kInfoHeader)
// BITMAPINFOHEADER
val info = kFileHeader
putU32LE(info + 0, kInfoHeader)
putU32LE(info + 4, inWidth)
putU32LE(info + 8, inHeight) // positive → bottom-up
putU16LE(info + 12, 1)
putU16LE(info + 14, 24)
putU32LE(info + 16, 0) // BI_RGB
putU32LE(info + 20, vPixelBytes)
putU32LE(info + 24, 2835)
putU32LE(info + 28, 2835)
putU32LE(info + 32, 0)
putU32LE(info + 36, 0)
// Source is top-down BGRA; convert to bottom-up 24-bit BGR.
val vPixelOffset = kFileHeader + kInfoHeader
for (y in 0 until inHeight) {
val vSrcRow = (inHeight - 1 - y) * inWidth * 4
val vDstRow = vPixelOffset + y * vStride
for (x in 0 until inWidth) {
vOut[vDstRow + x * 3 + 0] = inBgra[vSrcRow + x * 4 + 0] // B
vOut[vDstRow + x * 3 + 1] = inBgra[vSrcRow + x * 4 + 1] // G
vOut[vDstRow + x * 3 + 2] = inBgra[vSrcRow + x * 4 + 2] // R
}
}
return vOut
}
+92 -41
View File
@@ -32,27 +32,46 @@ val vPublishVersion = (System.getenv("PUBLISH_VERSION") ?: "0.0.0-SNAPSHOT").rem
// headline app-shell artifact, published under com.bitsycore.compose. // headline app-shell artifact, published under com.bitsycore.compose.
val kDefaultGroup = "com.bitsycore.compose.sdl" val kDefaultGroup = "com.bitsycore.compose.sdl"
val kAreaGroups = mapOf( val kAreaGroups = mapOf(
":ui" to "com.bitsycore.compose.ui", ":compose:ui:ui" to "com.bitsycore.compose.ui",
":ui-graphics" to "com.bitsycore.compose.ui", ":compose:ui:ui-graphics" to "com.bitsycore.compose.ui",
":ui-text" to "com.bitsycore.compose.ui", ":compose:ui:ui-text" to "com.bitsycore.compose.ui",
":ui-unit" to "com.bitsycore.compose.ui", ":compose:ui:ui-unit" to "com.bitsycore.compose.ui",
":ui-geometry" to "com.bitsycore.compose.ui", ":compose:ui:ui-geometry" to "com.bitsycore.compose.ui",
":ui-util" to "com.bitsycore.compose.ui", ":compose:ui:ui-util" to "com.bitsycore.compose.ui",
":ui-backhandler" to "com.bitsycore.compose.ui", ":compose:ui:ui-backhandler" to "com.bitsycore.compose.ui",
":ui-tooling-preview" to "com.bitsycore.compose.ui", ":compose:ui:ui-tooling-preview" to "com.bitsycore.compose.ui",
":foundation" to "com.bitsycore.compose.foundation", ":compose:foundation:foundation" to "com.bitsycore.compose.foundation",
":foundation-layout" to "com.bitsycore.compose.foundation", ":compose:foundation:foundation-layout" to "com.bitsycore.compose.foundation",
":animation" to "com.bitsycore.compose.animation", ":compose:animation:animation" to "com.bitsycore.compose.animation",
":animation-core" to "com.bitsycore.compose.animation", ":compose:animation:animation-core" to "com.bitsycore.compose.animation",
":animation-graphics" to "com.bitsycore.compose.animation", ":compose:animation:animation-graphics" to "com.bitsycore.compose.animation",
":material3" to "com.bitsycore.compose.material3", ":compose:material3:material3" to "com.bitsycore.compose.material3",
":material-ripple" to "com.bitsycore.compose.material", ":compose:material:material-ripple" to "com.bitsycore.compose.material",
":components-resources" to "com.bitsycore.compose.components", ":components:resources:components-resources" to "com.bitsycore.compose.components",
":navigation3-ui" to "com.bitsycore.navigation3", ":navigation3:navigation3-ui" to "com.bitsycore.navigation3",
":desktop-native-window" to "com.bitsycore.compose", ":koin:koin-core-viewmodel" to "com.bitsycore.koin",
":koin:koin-compose" to "com.bitsycore.koin",
":koin:koin-compose-viewmodel" to "com.bitsycore.koin",
":koin:koin-compose-navigation3" to "com.bitsycore.koin",
":coil:coil-core" to "com.bitsycore.coil3",
":coil:coil" to "com.bitsycore.coil3",
":coil:coil-compose-core" to "com.bitsycore.coil3",
":coil:coil-compose" to "com.bitsycore.coil3",
":coil:coil-svg" to "com.bitsycore.coil3",
":coil:coil-network-core" to "com.bitsycore.coil3",
":coil:coil-network-ktor3" to "com.bitsycore.coil3",
":pulse:pulse" to "com.bitsycore.pulse",
":pulse:pulse-viewmodel" to "com.bitsycore.pulse",
":pulse:pulse-savedstate" to "com.bitsycore.pulse",
":pulse:pulse-compose" to "com.bitsycore.pulse",
":compose:desktop:native:desktop-native-window" to "com.bitsycore.compose",
) )
fun groupFor(path: String): String = kAreaGroups[path] ?: kDefaultGroup fun groupFor(path: String): String = kAreaGroups[path] ?: kDefaultGroup
// The published artifactId is always the leaf project name - settings.gradle.kts
// keeps the leaf equal to the artifactId even where the directory differs.
fun artifactIdFor(path: String): String = path.substringAfterLast(':')
allprojects { allprojects {
group = groupFor(path) group = groupFor(path)
version = vPublishVersion version = vPublishVersion
@@ -72,14 +91,21 @@ allprojects {
val kAppModules = setOf(":demo", ":apidemo") val kAppModules = setOf(":demo", ":apidemo")
val kPublishedLibs = setOf( val kPublishedLibs = setOf(
":sdl-core", ":sdl:sdl-core",
":ui", ":ui-util", ":ui-geometry", ":ui-graphics", ":ui-text", ":compose:ui:ui", ":compose:ui:ui-util", ":compose:ui:ui-geometry",
":ui-unit", ":ui-backhandler", ":ui-tooling-preview", ":compose:ui:ui-graphics", ":compose:ui:ui-text",
":animation-core", ":animation", ":animation-graphics", ":compose:ui:ui-unit", ":compose:ui:ui-backhandler", ":compose:ui:ui-tooling-preview",
":foundation", ":foundation-layout", ":compose:animation:animation-core", ":compose:animation:animation",
":material3", ":material-ripple", ":compose:animation:animation-graphics",
":desktop-native-window", ":material-symbols", ":compose:foundation:foundation", ":compose:foundation:foundation-layout",
":navigation3-ui", ":components-resources", ":compose:material3:material3", ":compose:material:material-ripple",
":compose:desktop:native:desktop-native-window", ":utils:material-symbols",
":navigation3:navigation3-ui", ":components:resources:components-resources",
":koin:koin-core-viewmodel", ":koin:koin-compose",
":koin:koin-compose-viewmodel", ":koin:koin-compose-navigation3",
":coil:coil-core", ":coil:coil", ":coil:coil-compose-core", ":coil:coil-compose",
":coil:coil-svg", ":coil:coil-network-core", ":coil:coil-network-ktor3",
":pulse:pulse", ":pulse:pulse-viewmodel", ":pulse:pulse-savedstate", ":pulse:pulse-compose",
) )
// -PuseGithubPackages=true swaps every `project(":<lib>")` reference the demo // -PuseGithubPackages=true swaps every `project(":<lib>")` reference the demo
@@ -110,7 +136,7 @@ subprojects {
configurations.configureEach { configurations.configureEach {
resolutionStrategy.dependencySubstitution { resolutionStrategy.dependencySubstitution {
kPublishedLibs.forEach { modulePath -> kPublishedLibs.forEach { modulePath ->
val vArtifactId = modulePath.removePrefix(":") val vArtifactId = artifactIdFor(modulePath)
substitute(project(modulePath)) substitute(project(modulePath))
.using(module("${groupFor(modulePath)}:$vArtifactId:$kConsumeVersion")) .using(module("${groupFor(modulePath)}:$vArtifactId:$kConsumeVersion"))
.because("-PuseGithubPackages=true") .because("-PuseGithubPackages=true")
@@ -128,6 +154,9 @@ subprojects {
} }
return@subprojects return@subprojects
} }
// Nesting the paths under compose/ / sdl/ / utils/ … materialises container
// projects (:compose, :compose:ui, …) that hold no code - skip them.
if (path !in kPublishedLibs) return@subprojects
plugins.apply("maven-publish") plugins.apply("maven-publish")
afterEvaluate { afterEvaluate {
extensions.configure<PublishingExtension> { extensions.configure<PublishingExtension> {
@@ -178,27 +207,49 @@ allprojects {
configurations.configureEach { configurations.configureEach {
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(":compose:ui:ui"))
// ui-graphics / ui-text are their own modules (split out of :ui, // ui-graphics / ui-text are their own modules (split out of :ui,
// upstream layout). Declare each DIRECTLY so the app commonMain sees // upstream layout). Declare each DIRECTLY so the app commonMain sees
// them under the granular-metadata visibility rule. // them under the granular-metadata visibility rule.
substitute(module("org.jetbrains.compose.ui:ui-graphics")).using(project(":ui-graphics")) substitute(module("org.jetbrains.compose.ui:ui-graphics")).using(project(":compose:ui:ui-graphics"))
substitute(module("org.jetbrains.compose.ui:ui-text")).using(project(":ui-text")) substitute(module("org.jetbrains.compose.ui:ui-text")).using(project(":compose:ui:ui-text"))
substitute(module("org.jetbrains.compose.ui:ui-unit")).using(project(":ui-unit")) substitute(module("org.jetbrains.compose.ui:ui-unit")).using(project(":compose:ui:ui-unit"))
substitute(module("org.jetbrains.compose.ui:ui-geometry")).using(project(":ui-geometry")) substitute(module("org.jetbrains.compose.ui:ui-geometry")).using(project(":compose:ui:ui-geometry"))
substitute(module("org.jetbrains.compose.ui:ui-util")).using(project(":ui-util")) substitute(module("org.jetbrains.compose.ui:ui-util")).using(project(":compose:ui:ui-util"))
substitute(module("org.jetbrains.compose.ui:ui-tooling-preview")).using(project(":ui-tooling-preview")) substitute(module("org.jetbrains.compose.ui:ui-tooling-preview")).using(project(":compose:ui:ui-tooling-preview"))
substitute(module("org.jetbrains.compose.foundation:foundation")).using(project(":foundation")) substitute(module("org.jetbrains.compose.foundation:foundation")).using(project(":compose:foundation:foundation"))
substitute(module("org.jetbrains.compose.foundation:foundation-layout")).using(project(":foundation-layout")) substitute(module("org.jetbrains.compose.foundation:foundation-layout")).using(project(":compose:foundation:foundation-layout"))
substitute(module("org.jetbrains.compose.animation:animation")).using(project(":animation")) substitute(module("org.jetbrains.compose.animation:animation")).using(project(":compose:animation:animation"))
substitute(module("org.jetbrains.compose.animation:animation-core")).using(project(":animation-core")) substitute(module("org.jetbrains.compose.animation:animation-core")).using(project(":compose:animation:animation-core"))
substitute(module("org.jetbrains.compose.material3:material3")).using(project(":material3")) substitute(module("org.jetbrains.compose.material3:material3")).using(project(":compose:material3:material3"))
// navigation3-ui: the JB Maven artifact has no K/N desktop // navigation3-ui: the JB Maven artifact has no K/N desktop
// klibs - the port vendors it as :navigation3-ui. // klibs - the port vendors it as :navigation3-ui.
substitute(module("org.jetbrains.androidx.navigation3:navigation3-ui")).using(project(":navigation3-ui")) substitute(module("org.jetbrains.androidx.navigation3:navigation3-ui")).using(project(":navigation3:navigation3-ui"))
// components-resources: the official resources runtime ships no // components-resources: the official resources runtime ships no
// mingwX64/linux klibs - the port vendors it as :components-resources. // mingwX64/linux klibs - the port vendors it as :components-resources.
substitute(module("org.jetbrains.compose.components:components-resources")).using(project(":components-resources")) substitute(module("org.jetbrains.compose.components:components-resources")).using(project(":components:resources:components-resources"))
// Koin: koin-core itself publishes mingwX64 + linux and is used
// from Maven; these four stop at apple+android upstream.
substitute(module("io.insert-koin:koin-core-viewmodel")).using(project(":koin:koin-core-viewmodel"))
substitute(module("io.insert-koin:koin-compose")).using(project(":koin:koin-compose"))
substitute(module("io.insert-koin:koin-compose-viewmodel")).using(project(":koin:koin-compose-viewmodel"))
substitute(module("io.insert-koin:koin-compose-navigation3")).using(project(":koin:koin-compose-navigation3"))
// Coil 3: no mingwX64 upstream anywhere, and no linux for the
// compose layer either.
substitute(module("io.coil-kt.coil3:coil-core")).using(project(":coil:coil-core"))
substitute(module("io.coil-kt.coil3:coil")).using(project(":coil:coil"))
substitute(module("io.coil-kt.coil3:coil-compose-core")).using(project(":coil:coil-compose-core"))
substitute(module("io.coil-kt.coil3:coil-compose")).using(project(":coil:coil-compose"))
substitute(module("io.coil-kt.coil3:coil-svg")).using(project(":coil:coil-svg"))
substitute(module("io.coil-kt.coil3:coil-network-core")).using(project(":coil:coil-network-core"))
substitute(module("io.coil-kt.coil3:coil-network-ktor3")).using(project(":coil:coil-network-ktor3"))
// Pulse MVI: upstream publishes com.bitsycore.lib:* with no desktop
// native targets. The port republishes under com.bitsycore.pulse so the
// two coordinates never collide, and substitutes the official one here.
substitute(module("com.bitsycore.lib:pulse")).using(project(":pulse:pulse"))
substitute(module("com.bitsycore.lib:pulse-viewmodel")).using(project(":pulse:pulse-viewmodel"))
substitute(module("com.bitsycore.lib:pulse-savedstate")).using(project(":pulse:pulse-savedstate"))
substitute(module("com.bitsycore.lib:pulse-compose")).using(project(":pulse:pulse-compose"))
} }
} }
} }
@@ -197,7 +197,7 @@ private fun Project.addFontEntries(
inTask.from(vNotoFile) { into("font") } inTask.from(vNotoFile) { into("font") }
inDownloadNotoFonts?.let { inTask.dependsOn(it) } inDownloadNotoFonts?.let { inTask.dependsOn(it) }
} }
val vSymbolsProject = rootProject.project(":material-symbols") val vSymbolsProject = rootProject.project(":utils:material-symbols")
for (vStyle in inUsedStyles) { for (vStyle in inUsedStyles) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val vFontFile = vSymbolsProject.extra["iconFontFile$vStyle"] as Provider<RegularFile> val vFontFile = vSymbolsProject.extra["iconFontFile$vStyle"] as Provider<RegularFile>
@@ -232,7 +232,7 @@ private fun Project.registerIconSubsetPipeline(inUsedStyles: List<String>): Map<
val vFindUsage = tasks.register<Exec>("findMaterialSymbolsUsage") { val vFindUsage = tasks.register<Exec>("findMaterialSymbolsUsage") {
description = "Scan src/ for MaterialSymbols.<Name> usages → usage-codepoint.txt." description = "Scan src/ for MaterialSymbols.<Name> usages → usage-codepoint.txt."
val vScript = rootProject.layout.projectDirectory.file("scripts/subset-material-symbols.py").asFile val vScript = rootProject.layout.projectDirectory.file("scripts/subset-material-symbols.py").asFile
val vConstants = rootProject.project(":material-symbols").layout.projectDirectory val vConstants = rootProject.project(":utils:material-symbols").layout.projectDirectory
.file("src/commonMain/kotlin/com/compose/sdl/icons/MaterialSymbols.kt").asFile .file("src/commonMain/kotlin/com/compose/sdl/icons/MaterialSymbols.kt").asFile
val vUsageFile = vIconsBuildDir.get().file("usage-codepoint.txt").asFile val vUsageFile = vIconsBuildDir.get().file("usage-codepoint.txt").asFile
inputs.files(fileTree("src") { include("**/*.kt") }) inputs.files(fileTree("src") { include("**/*.kt") })
@@ -259,7 +259,7 @@ private fun Project.registerSubsetTask(
inIconsBuildDir: Provider<Directory>, inIconsBuildDir: Provider<Directory>,
inFindUsage: TaskProvider<*>, inFindUsage: TaskProvider<*>,
): TaskProvider<*> { ): TaskProvider<*> {
val vSymbolsProject = rootProject.project(":material-symbols") val vSymbolsProject = rootProject.project(":utils:material-symbols")
return tasks.register("subsetMaterialSymbols$inStyle") { return tasks.register("subsetMaterialSymbols$inStyle") {
description = "hb-subset the $inStyle Material Symbols font to icons actually used." description = "hb-subset the $inStyle Material Symbols font to icons actually used."
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@@ -0,0 +1,240 @@
// 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.coil3:coil-compose-core>
abstract fun interface coil3.compose/AsyncImagePreviewHandler { // coil3.compose/AsyncImagePreviewHandler|null[0]
abstract suspend fun handle(coil3/ImageLoader, coil3.request/ImageRequest): coil3.compose/AsyncImagePainter.State // coil3.compose/AsyncImagePreviewHandler.handle|handle(coil3.ImageLoader;coil3.request.ImageRequest){}[0]
final object Companion { // coil3.compose/AsyncImagePreviewHandler.Companion|null[0]
final val Default // coil3.compose/AsyncImagePreviewHandler.Companion.Default|{}Default[0]
final fun <get-Default>(): coil3.compose/AsyncImagePreviewHandler // coil3.compose/AsyncImagePreviewHandler.Companion.Default.<get-Default>|<get-Default>(){}[0]
}
}
abstract interface coil3.compose/AsyncImageModelEqualityDelegate { // coil3.compose/AsyncImageModelEqualityDelegate|null[0]
abstract fun equals(kotlin/Any?, kotlin/Any?): kotlin/Boolean // coil3.compose/AsyncImageModelEqualityDelegate.equals|equals(kotlin.Any?;kotlin.Any?){}[0]
abstract fun hashCode(kotlin/Any?): kotlin/Int // coil3.compose/AsyncImageModelEqualityDelegate.hashCode|hashCode(kotlin.Any?){}[0]
final object Companion { // coil3.compose/AsyncImageModelEqualityDelegate.Companion|null[0]
final val AllProperties // coil3.compose/AsyncImageModelEqualityDelegate.Companion.AllProperties|{}AllProperties[0]
final fun <get-AllProperties>(): coil3.compose/AsyncImageModelEqualityDelegate // coil3.compose/AsyncImageModelEqualityDelegate.Companion.AllProperties.<get-AllProperties>|<get-AllProperties>(){}[0]
final val Default // coil3.compose/AsyncImageModelEqualityDelegate.Companion.Default|{}Default[0]
final fun <get-Default>(): coil3.compose/AsyncImageModelEqualityDelegate // coil3.compose/AsyncImageModelEqualityDelegate.Companion.Default.<get-Default>|<get-Default>(){}[0]
}
}
abstract interface coil3.compose/DrawScopeSizeResolver : coil3.size/SizeResolver { // coil3.compose/DrawScopeSizeResolver|null[0]
abstract fun connect(kotlinx.coroutines.flow/Flow<androidx.compose.ui.geometry/Size>) // coil3.compose/DrawScopeSizeResolver.connect|connect(kotlinx.coroutines.flow.Flow<androidx.compose.ui.geometry.Size>){}[0]
}
abstract interface coil3.compose/SubcomposeAsyncImageScope : androidx.compose.foundation.layout/BoxScope { // coil3.compose/SubcomposeAsyncImageScope|null[0]
abstract val alignment // coil3.compose/SubcomposeAsyncImageScope.alignment|{}alignment[0]
abstract fun <get-alignment>(): androidx.compose.ui/Alignment // coil3.compose/SubcomposeAsyncImageScope.alignment.<get-alignment>|<get-alignment>(){}[0]
abstract val alpha // coil3.compose/SubcomposeAsyncImageScope.alpha|{}alpha[0]
abstract fun <get-alpha>(): kotlin/Float // coil3.compose/SubcomposeAsyncImageScope.alpha.<get-alpha>|<get-alpha>(){}[0]
abstract val clipToBounds // coil3.compose/SubcomposeAsyncImageScope.clipToBounds|{}clipToBounds[0]
abstract fun <get-clipToBounds>(): kotlin/Boolean // coil3.compose/SubcomposeAsyncImageScope.clipToBounds.<get-clipToBounds>|<get-clipToBounds>(){}[0]
abstract val colorFilter // coil3.compose/SubcomposeAsyncImageScope.colorFilter|{}colorFilter[0]
abstract fun <get-colorFilter>(): androidx.compose.ui.graphics/ColorFilter? // coil3.compose/SubcomposeAsyncImageScope.colorFilter.<get-colorFilter>|<get-colorFilter>(){}[0]
abstract val contentDescription // coil3.compose/SubcomposeAsyncImageScope.contentDescription|{}contentDescription[0]
abstract fun <get-contentDescription>(): kotlin/String? // coil3.compose/SubcomposeAsyncImageScope.contentDescription.<get-contentDescription>|<get-contentDescription>(){}[0]
abstract val contentScale // coil3.compose/SubcomposeAsyncImageScope.contentScale|{}contentScale[0]
abstract fun <get-contentScale>(): androidx.compose.ui.layout/ContentScale // coil3.compose/SubcomposeAsyncImageScope.contentScale.<get-contentScale>|<get-contentScale>(){}[0]
abstract val painter // coil3.compose/SubcomposeAsyncImageScope.painter|{}painter[0]
abstract fun <get-painter>(): coil3.compose/AsyncImagePainter // coil3.compose/SubcomposeAsyncImageScope.painter.<get-painter>|<get-painter>(){}[0]
}
final class coil3.compose/AsyncImagePainter : androidx.compose.runtime/RememberObserver, androidx.compose.ui.graphics.painter/Painter { // coil3.compose/AsyncImagePainter|null[0]
final val input // coil3.compose/AsyncImagePainter.input|{}input[0]
final fun <get-input>(): kotlinx.coroutines.flow/StateFlow<coil3.compose/AsyncImagePainter.Input> // coil3.compose/AsyncImagePainter.input.<get-input>|<get-input>(){}[0]
final val intrinsicSize // coil3.compose/AsyncImagePainter.intrinsicSize|{}intrinsicSize[0]
final fun <get-intrinsicSize>(): androidx.compose.ui.geometry/Size // coil3.compose/AsyncImagePainter.intrinsicSize.<get-intrinsicSize>|<get-intrinsicSize>(){}[0]
final val state // coil3.compose/AsyncImagePainter.state|{}state[0]
final fun <get-state>(): kotlinx.coroutines.flow/StateFlow<coil3.compose/AsyncImagePainter.State> // coil3.compose/AsyncImagePainter.state.<get-state>|<get-state>(){}[0]
final fun onAbandoned() // coil3.compose/AsyncImagePainter.onAbandoned|onAbandoned(){}[0]
final fun onForgotten() // coil3.compose/AsyncImagePainter.onForgotten|onForgotten(){}[0]
final fun onRemembered() // coil3.compose/AsyncImagePainter.onRemembered|onRemembered(){}[0]
final fun restart() // coil3.compose/AsyncImagePainter.restart|restart(){}[0]
sealed interface State { // coil3.compose/AsyncImagePainter.State|null[0]
abstract val painter // coil3.compose/AsyncImagePainter.State.painter|{}painter[0]
abstract fun <get-painter>(): androidx.compose.ui.graphics.painter/Painter? // coil3.compose/AsyncImagePainter.State.painter.<get-painter>|<get-painter>(){}[0]
final class Error : coil3.compose/AsyncImagePainter.State { // coil3.compose/AsyncImagePainter.State.Error|null[0]
constructor <init>(androidx.compose.ui.graphics.painter/Painter?, coil3.request/ErrorResult) // coil3.compose/AsyncImagePainter.State.Error.<init>|<init>(androidx.compose.ui.graphics.painter.Painter?;coil3.request.ErrorResult){}[0]
final val painter // coil3.compose/AsyncImagePainter.State.Error.painter|{}painter[0]
final fun <get-painter>(): androidx.compose.ui.graphics.painter/Painter? // coil3.compose/AsyncImagePainter.State.Error.painter.<get-painter>|<get-painter>(){}[0]
final val result // coil3.compose/AsyncImagePainter.State.Error.result|{}result[0]
final fun <get-result>(): coil3.request/ErrorResult // coil3.compose/AsyncImagePainter.State.Error.result.<get-result>|<get-result>(){}[0]
final fun component1(): androidx.compose.ui.graphics.painter/Painter? // coil3.compose/AsyncImagePainter.State.Error.component1|component1(){}[0]
final fun component2(): coil3.request/ErrorResult // coil3.compose/AsyncImagePainter.State.Error.component2|component2(){}[0]
final fun copy(androidx.compose.ui.graphics.painter/Painter? = ..., coil3.request/ErrorResult = ...): coil3.compose/AsyncImagePainter.State.Error // coil3.compose/AsyncImagePainter.State.Error.copy|copy(androidx.compose.ui.graphics.painter.Painter?;coil3.request.ErrorResult){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // coil3.compose/AsyncImagePainter.State.Error.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // coil3.compose/AsyncImagePainter.State.Error.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // coil3.compose/AsyncImagePainter.State.Error.toString|toString(){}[0]
}
final class Loading : coil3.compose/AsyncImagePainter.State { // coil3.compose/AsyncImagePainter.State.Loading|null[0]
constructor <init>(androidx.compose.ui.graphics.painter/Painter?) // coil3.compose/AsyncImagePainter.State.Loading.<init>|<init>(androidx.compose.ui.graphics.painter.Painter?){}[0]
final val painter // coil3.compose/AsyncImagePainter.State.Loading.painter|{}painter[0]
final fun <get-painter>(): androidx.compose.ui.graphics.painter/Painter? // coil3.compose/AsyncImagePainter.State.Loading.painter.<get-painter>|<get-painter>(){}[0]
final fun component1(): androidx.compose.ui.graphics.painter/Painter? // coil3.compose/AsyncImagePainter.State.Loading.component1|component1(){}[0]
final fun copy(androidx.compose.ui.graphics.painter/Painter? = ...): coil3.compose/AsyncImagePainter.State.Loading // coil3.compose/AsyncImagePainter.State.Loading.copy|copy(androidx.compose.ui.graphics.painter.Painter?){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // coil3.compose/AsyncImagePainter.State.Loading.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // coil3.compose/AsyncImagePainter.State.Loading.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // coil3.compose/AsyncImagePainter.State.Loading.toString|toString(){}[0]
}
final class Success : coil3.compose/AsyncImagePainter.State { // coil3.compose/AsyncImagePainter.State.Success|null[0]
constructor <init>(androidx.compose.ui.graphics.painter/Painter, coil3.request/SuccessResult) // coil3.compose/AsyncImagePainter.State.Success.<init>|<init>(androidx.compose.ui.graphics.painter.Painter;coil3.request.SuccessResult){}[0]
final val painter // coil3.compose/AsyncImagePainter.State.Success.painter|{}painter[0]
final fun <get-painter>(): androidx.compose.ui.graphics.painter/Painter // coil3.compose/AsyncImagePainter.State.Success.painter.<get-painter>|<get-painter>(){}[0]
final val result // coil3.compose/AsyncImagePainter.State.Success.result|{}result[0]
final fun <get-result>(): coil3.request/SuccessResult // coil3.compose/AsyncImagePainter.State.Success.result.<get-result>|<get-result>(){}[0]
final fun component1(): androidx.compose.ui.graphics.painter/Painter // coil3.compose/AsyncImagePainter.State.Success.component1|component1(){}[0]
final fun component2(): coil3.request/SuccessResult // coil3.compose/AsyncImagePainter.State.Success.component2|component2(){}[0]
final fun copy(androidx.compose.ui.graphics.painter/Painter = ..., coil3.request/SuccessResult = ...): coil3.compose/AsyncImagePainter.State.Success // coil3.compose/AsyncImagePainter.State.Success.copy|copy(androidx.compose.ui.graphics.painter.Painter;coil3.request.SuccessResult){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // coil3.compose/AsyncImagePainter.State.Success.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // coil3.compose/AsyncImagePainter.State.Success.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // coil3.compose/AsyncImagePainter.State.Success.toString|toString(){}[0]
}
final object Empty : coil3.compose/AsyncImagePainter.State { // coil3.compose/AsyncImagePainter.State.Empty|null[0]
final val painter // coil3.compose/AsyncImagePainter.State.Empty.painter|{}painter[0]
final fun <get-painter>(): androidx.compose.ui.graphics.painter/Painter? // coil3.compose/AsyncImagePainter.State.Empty.painter.<get-painter>|<get-painter>(){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // coil3.compose/AsyncImagePainter.State.Empty.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // coil3.compose/AsyncImagePainter.State.Empty.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // coil3.compose/AsyncImagePainter.State.Empty.toString|toString(){}[0]
}
}
final class Input { // coil3.compose/AsyncImagePainter.Input|null[0]
constructor <init>(coil3/ImageLoader, coil3.request/ImageRequest, coil3.compose/AsyncImageModelEqualityDelegate) // coil3.compose/AsyncImagePainter.Input.<init>|<init>(coil3.ImageLoader;coil3.request.ImageRequest;coil3.compose.AsyncImageModelEqualityDelegate){}[0]
final val imageLoader // coil3.compose/AsyncImagePainter.Input.imageLoader|{}imageLoader[0]
final fun <get-imageLoader>(): coil3/ImageLoader // coil3.compose/AsyncImagePainter.Input.imageLoader.<get-imageLoader>|<get-imageLoader>(){}[0]
final val modelEqualityDelegate // coil3.compose/AsyncImagePainter.Input.modelEqualityDelegate|{}modelEqualityDelegate[0]
final fun <get-modelEqualityDelegate>(): coil3.compose/AsyncImageModelEqualityDelegate // coil3.compose/AsyncImagePainter.Input.modelEqualityDelegate.<get-modelEqualityDelegate>|<get-modelEqualityDelegate>(){}[0]
final val request // coil3.compose/AsyncImagePainter.Input.request|{}request[0]
final fun <get-request>(): coil3.request/ImageRequest // coil3.compose/AsyncImagePainter.Input.request.<get-request>|<get-request>(){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // coil3.compose/AsyncImagePainter.Input.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // coil3.compose/AsyncImagePainter.Input.hashCode|hashCode(){}[0]
}
final object Companion { // coil3.compose/AsyncImagePainter.Companion|null[0]
final val DefaultTransform // coil3.compose/AsyncImagePainter.Companion.DefaultTransform|{}DefaultTransform[0]
final fun <get-DefaultTransform>(): kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State> // coil3.compose/AsyncImagePainter.Companion.DefaultTransform.<get-DefaultTransform>|<get-DefaultTransform>(){}[0]
}
}
final class coil3.compose/ConstraintsSizeResolver : androidx.compose.ui.layout/LayoutModifier, coil3.size/SizeResolver { // coil3.compose/ConstraintsSizeResolver|null[0]
constructor <init>() // coil3.compose/ConstraintsSizeResolver.<init>|<init>(){}[0]
final fun (androidx.compose.ui.layout/MeasureScope).measure(androidx.compose.ui.layout/Measurable, androidx.compose.ui.unit/Constraints): androidx.compose.ui.layout/MeasureResult // coil3.compose/ConstraintsSizeResolver.measure|measure@androidx.compose.ui.layout.MeasureScope(androidx.compose.ui.layout.Measurable;androidx.compose.ui.unit.Constraints){}[0]
final fun setConstraints(androidx.compose.ui.unit/Constraints) // coil3.compose/ConstraintsSizeResolver.setConstraints|setConstraints(androidx.compose.ui.unit.Constraints){}[0]
final suspend fun size(): coil3.size/Size // coil3.compose/ConstraintsSizeResolver.size|size(){}[0]
}
final class coil3.compose/CrossfadePainter : androidx.compose.ui.graphics.painter/Painter { // coil3.compose/CrossfadePainter|null[0]
constructor <init>(androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.layout/ContentScale = ..., kotlin.time/Duration = ..., kotlin.time/TimeSource = ..., kotlin/Boolean = ..., kotlin/Boolean = ...) // coil3.compose/CrossfadePainter.<init>|<init>(androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.layout.ContentScale;kotlin.time.Duration;kotlin.time.TimeSource;kotlin.Boolean;kotlin.Boolean){}[0]
constructor <init>(androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.layout/ContentScale = ..., kotlin.time/Duration = ..., kotlin.time/TimeSource = ..., kotlin/Boolean = ..., kotlin/Boolean = ..., kotlin/Boolean = ...) // coil3.compose/CrossfadePainter.<init>|<init>(androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.layout.ContentScale;kotlin.time.Duration;kotlin.time.TimeSource;kotlin.Boolean;kotlin.Boolean;kotlin.Boolean){}[0]
final val contentScale // coil3.compose/CrossfadePainter.contentScale|{}contentScale[0]
final fun <get-contentScale>(): androidx.compose.ui.layout/ContentScale // coil3.compose/CrossfadePainter.contentScale.<get-contentScale>|<get-contentScale>(){}[0]
final val duration // coil3.compose/CrossfadePainter.duration|{}duration[0]
final fun <get-duration>(): kotlin.time/Duration // coil3.compose/CrossfadePainter.duration.<get-duration>|<get-duration>(){}[0]
final val end // coil3.compose/CrossfadePainter.end|{}end[0]
final fun <get-end>(): androidx.compose.ui.graphics.painter/Painter? // coil3.compose/CrossfadePainter.end.<get-end>|<get-end>(){}[0]
final val fadeStart // coil3.compose/CrossfadePainter.fadeStart|{}fadeStart[0]
final fun <get-fadeStart>(): kotlin/Boolean // coil3.compose/CrossfadePainter.fadeStart.<get-fadeStart>|<get-fadeStart>(){}[0]
final val intrinsicSize // coil3.compose/CrossfadePainter.intrinsicSize|{}intrinsicSize[0]
final fun <get-intrinsicSize>(): androidx.compose.ui.geometry/Size // coil3.compose/CrossfadePainter.intrinsicSize.<get-intrinsicSize>|<get-intrinsicSize>(){}[0]
final val preferEndFirstIntrinsicSize // coil3.compose/CrossfadePainter.preferEndFirstIntrinsicSize|{}preferEndFirstIntrinsicSize[0]
final fun <get-preferEndFirstIntrinsicSize>(): kotlin/Boolean // coil3.compose/CrossfadePainter.preferEndFirstIntrinsicSize.<get-preferEndFirstIntrinsicSize>|<get-preferEndFirstIntrinsicSize>(){}[0]
final val preferExactIntrinsicSize // coil3.compose/CrossfadePainter.preferExactIntrinsicSize|{}preferExactIntrinsicSize[0]
final fun <get-preferExactIntrinsicSize>(): kotlin/Boolean // coil3.compose/CrossfadePainter.preferExactIntrinsicSize.<get-preferExactIntrinsicSize>|<get-preferExactIntrinsicSize>(){}[0]
final val timeSource // coil3.compose/CrossfadePainter.timeSource|{}timeSource[0]
final fun <get-timeSource>(): kotlin.time/TimeSource // coil3.compose/CrossfadePainter.timeSource.<get-timeSource>|<get-timeSource>(){}[0]
final var start // coil3.compose/CrossfadePainter.start|{}start[0]
final fun <get-start>(): androidx.compose.ui.graphics.painter/Painter? // coil3.compose/CrossfadePainter.start.<get-start>|<get-start>(){}[0]
}
final class coil3.compose/ImagePainter : androidx.compose.ui.graphics.painter/Painter { // coil3.compose/ImagePainter|null[0]
constructor <init>(coil3/Image) // coil3.compose/ImagePainter.<init>|<init>(coil3.Image){}[0]
final val image // coil3.compose/ImagePainter.image|{}image[0]
final fun <get-image>(): coil3/Image // coil3.compose/ImagePainter.image.<get-image>|<get-image>(){}[0]
final val intrinsicSize // coil3.compose/ImagePainter.intrinsicSize|{}intrinsicSize[0]
final fun <get-intrinsicSize>(): androidx.compose.ui.geometry/Size // coil3.compose/ImagePainter.intrinsicSize.<get-intrinsicSize>|<get-intrinsicSize>(){}[0]
}
final val coil3.compose/LocalAsyncImageModelEqualityDelegate // coil3.compose/LocalAsyncImageModelEqualityDelegate|{}LocalAsyncImageModelEqualityDelegate[0]
final fun <get-LocalAsyncImageModelEqualityDelegate>(): androidx.compose.runtime/ProvidableCompositionLocal<coil3.compose/AsyncImageModelEqualityDelegate> // coil3.compose/LocalAsyncImageModelEqualityDelegate.<get-LocalAsyncImageModelEqualityDelegate>|<get-LocalAsyncImageModelEqualityDelegate>(){}[0]
final val coil3.compose/LocalAsyncImagePreviewHandler // coil3.compose/LocalAsyncImagePreviewHandler|{}LocalAsyncImagePreviewHandler[0]
final fun <get-LocalAsyncImagePreviewHandler>(): androidx.compose.runtime/ProvidableCompositionLocal<coil3.compose/AsyncImagePreviewHandler> // coil3.compose/LocalAsyncImagePreviewHandler.<get-LocalAsyncImagePreviewHandler>|<get-LocalAsyncImagePreviewHandler>(){}[0]
final val coil3.compose/LocalPlatformContext // coil3.compose/LocalPlatformContext|{}LocalPlatformContext[0]
final fun <get-LocalPlatformContext>(): androidx.compose.runtime/ProvidableCompositionLocal<coil3/PlatformContext> // coil3.compose/LocalPlatformContext.<get-LocalPlatformContext>|<get-LocalPlatformContext>(){}[0]
final val coil3.compose/coil3_compose_AsyncImagePainter$stableprop // coil3.compose/coil3_compose_AsyncImagePainter$stableprop|#static{}coil3_compose_AsyncImagePainter$stableprop[0]
final val coil3.compose/coil3_compose_AsyncImagePainter_Input$stableprop // coil3.compose/coil3_compose_AsyncImagePainter_Input$stableprop|#static{}coil3_compose_AsyncImagePainter_Input$stableprop[0]
final val coil3.compose/coil3_compose_AsyncImagePainter_State_Empty$stableprop // coil3.compose/coil3_compose_AsyncImagePainter_State_Empty$stableprop|#static{}coil3_compose_AsyncImagePainter_State_Empty$stableprop[0]
final val coil3.compose/coil3_compose_AsyncImagePainter_State_Error$stableprop // coil3.compose/coil3_compose_AsyncImagePainter_State_Error$stableprop|#static{}coil3_compose_AsyncImagePainter_State_Error$stableprop[0]
final val coil3.compose/coil3_compose_AsyncImagePainter_State_Loading$stableprop // coil3.compose/coil3_compose_AsyncImagePainter_State_Loading$stableprop|#static{}coil3_compose_AsyncImagePainter_State_Loading$stableprop[0]
final val coil3.compose/coil3_compose_AsyncImagePainter_State_Success$stableprop // coil3.compose/coil3_compose_AsyncImagePainter_State_Success$stableprop|#static{}coil3_compose_AsyncImagePainter_State_Success$stableprop[0]
final val coil3.compose/coil3_compose_ConstraintsSizeResolver$stableprop // coil3.compose/coil3_compose_ConstraintsSizeResolver$stableprop|#static{}coil3_compose_ConstraintsSizeResolver$stableprop[0]
final val coil3.compose/coil3_compose_CrossfadePainter$stableprop // coil3.compose/coil3_compose_CrossfadePainter$stableprop|#static{}coil3_compose_CrossfadePainter$stableprop[0]
final val coil3.compose/coil3_compose_ImagePainter$stableprop // coil3.compose/coil3_compose_ImagePainter$stableprop|#static{}coil3_compose_ImagePainter$stableprop[0]
final val coil3.compose/preferEndFirstIntrinsicSize // coil3.compose/preferEndFirstIntrinsicSize|@coil3.Extras.Key.Companion{}preferEndFirstIntrinsicSize[0]
final fun (coil3/Extras.Key.Companion).<get-preferEndFirstIntrinsicSize>(): coil3/Extras.Key<kotlin/Boolean> // coil3.compose/preferEndFirstIntrinsicSize.<get-preferEndFirstIntrinsicSize>|<get-preferEndFirstIntrinsicSize>@coil3.Extras.Key.Companion(){}[0]
final val coil3.compose/preferEndFirstIntrinsicSize // coil3.compose/preferEndFirstIntrinsicSize|@coil3.request.ImageRequest{}preferEndFirstIntrinsicSize[0]
final fun (coil3.request/ImageRequest).<get-preferEndFirstIntrinsicSize>(): kotlin/Boolean // coil3.compose/preferEndFirstIntrinsicSize.<get-preferEndFirstIntrinsicSize>|<get-preferEndFirstIntrinsicSize>@coil3.request.ImageRequest(){}[0]
final val coil3.compose/useExistingImageAsPlaceholder // coil3.compose/useExistingImageAsPlaceholder|@coil3.Extras.Key.Companion{}useExistingImageAsPlaceholder[0]
final fun (coil3/Extras.Key.Companion).<get-useExistingImageAsPlaceholder>(): coil3/Extras.Key<kotlin/Boolean> // coil3.compose/useExistingImageAsPlaceholder.<get-useExistingImageAsPlaceholder>|<get-useExistingImageAsPlaceholder>@coil3.Extras.Key.Companion(){}[0]
final val coil3.compose/useExistingImageAsPlaceholder // coil3.compose/useExistingImageAsPlaceholder|@coil3.request.ImageRequest{}useExistingImageAsPlaceholder[0]
final fun (coil3.request/ImageRequest).<get-useExistingImageAsPlaceholder>(): kotlin/Boolean // coil3.compose/useExistingImageAsPlaceholder.<get-useExistingImageAsPlaceholder>|<get-useExistingImageAsPlaceholder>@coil3.request.ImageRequest(){}[0]
final fun (coil3.compose/SubcomposeAsyncImageScope).coil3.compose/SubcomposeAsyncImageContent(androidx.compose.ui/Modifier?, androidx.compose.ui.graphics.painter/Painter?, kotlin/String?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // coil3.compose/SubcomposeAsyncImageContent|SubcomposeAsyncImageContent@coil3.compose.SubcomposeAsyncImageScope(androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.painter.Painter?;kotlin.String?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun (coil3.request/ImageRequest.Builder).coil3.compose/preferEndFirstIntrinsicSize(kotlin/Boolean): coil3.request/ImageRequest.Builder // coil3.compose/preferEndFirstIntrinsicSize|preferEndFirstIntrinsicSize@coil3.request.ImageRequest.Builder(kotlin.Boolean){}[0]
final fun (coil3.request/ImageRequest.Builder).coil3.compose/useExistingImageAsPlaceholder(kotlin/Boolean): coil3.request/ImageRequest.Builder // coil3.compose/useExistingImageAsPlaceholder|useExistingImageAsPlaceholder@coil3.request.ImageRequest.Builder(kotlin.Boolean){}[0]
final fun (coil3/Image).coil3.compose/asPainter(coil3/PlatformContext, androidx.compose.ui.graphics/FilterQuality = ...): androidx.compose.ui.graphics.painter/Painter // coil3.compose/asPainter|asPainter@coil3.Image(coil3.PlatformContext;androidx.compose.ui.graphics.FilterQuality){}[0]
final fun (coil3/ImageLoader.Builder).coil3.compose/preferEndFirstIntrinsicSize(kotlin/Boolean): coil3/ImageLoader.Builder // coil3.compose/preferEndFirstIntrinsicSize|preferEndFirstIntrinsicSize@coil3.ImageLoader.Builder(kotlin.Boolean){}[0]
final fun (coil3/ImageLoader.Builder).coil3.compose/useExistingImageAsPlaceholder(kotlin/Boolean): coil3/ImageLoader.Builder // coil3.compose/useExistingImageAsPlaceholder|useExistingImageAsPlaceholder@coil3.ImageLoader.Builder(kotlin.Boolean){}[0]
final fun coil3.compose/AsyncImage(kotlin/Any?, kotlin/String?, coil3/ImageLoader, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/AsyncImage|AsyncImage(kotlin.Any?;kotlin.String?;coil3.ImageLoader;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/AsyncImage(kotlin/Any?, kotlin/String?, coil3/ImageLoader, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality?, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/AsyncImage|AsyncImage(kotlin.Any?;kotlin.String?;coil3.ImageLoader;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality?;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/AsyncImage(kotlin/Any?, kotlin/String?, coil3/ImageLoader, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/AsyncImage|AsyncImage(kotlin.Any?;kotlin.String?;coil3.ImageLoader;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/AsyncImage(kotlin/Any?, kotlin/String?, coil3/ImageLoader, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality?, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/AsyncImage|AsyncImage(kotlin.Any?;kotlin.String?;coil3.ImageLoader;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality?;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/DrawScopeSizeResolver(): coil3.compose/DrawScopeSizeResolver // coil3.compose/DrawScopeSizeResolver|DrawScopeSizeResolver(){}[0]
final fun coil3.compose/SubcomposeAsyncImage(kotlin/Any?, kotlin/String?, coil3/ImageLoader, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, kotlin/Boolean, kotlin/Function3<coil3.compose/SubcomposeAsyncImageScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/SubcomposeAsyncImage|SubcomposeAsyncImage(kotlin.Any?;kotlin.String?;coil3.ImageLoader;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;kotlin.Boolean;kotlin.Function3<coil3.compose.SubcomposeAsyncImageScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/SubcomposeAsyncImage(kotlin/Any?, kotlin/String?, coil3/ImageLoader, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality?, kotlin/Boolean, kotlin/Function3<coil3.compose/SubcomposeAsyncImageScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/SubcomposeAsyncImage|SubcomposeAsyncImage(kotlin.Any?;kotlin.String?;coil3.ImageLoader;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality?;kotlin.Boolean;kotlin.Function3<coil3.compose.SubcomposeAsyncImageScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/SubcomposeAsyncImage(kotlin/Any?, kotlin/String?, coil3/ImageLoader, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Loading, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Success, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Error, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/SubcomposeAsyncImage|SubcomposeAsyncImage(kotlin.Any?;kotlin.String?;coil3.ImageLoader;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Loading,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Success,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Error,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/SubcomposeAsyncImage(kotlin/Any?, kotlin/String?, coil3/ImageLoader, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Loading, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Success, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Error, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality?, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/SubcomposeAsyncImage|SubcomposeAsyncImage(kotlin.Any?;kotlin.String?;coil3.ImageLoader;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Loading,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Success,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Error,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality?;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/coil3_compose_AsyncImagePainter$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_AsyncImagePainter$stableprop_getter|coil3_compose_AsyncImagePainter$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_AsyncImagePainter_Input$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_AsyncImagePainter_Input$stableprop_getter|coil3_compose_AsyncImagePainter_Input$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_AsyncImagePainter_State_Empty$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_AsyncImagePainter_State_Empty$stableprop_getter|coil3_compose_AsyncImagePainter_State_Empty$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_AsyncImagePainter_State_Error$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_AsyncImagePainter_State_Error$stableprop_getter|coil3_compose_AsyncImagePainter_State_Error$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_AsyncImagePainter_State_Loading$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_AsyncImagePainter_State_Loading$stableprop_getter|coil3_compose_AsyncImagePainter_State_Loading$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_AsyncImagePainter_State_Success$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_AsyncImagePainter_State_Success$stableprop_getter|coil3_compose_AsyncImagePainter_State_Success$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_ConstraintsSizeResolver$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_ConstraintsSizeResolver$stableprop_getter|coil3_compose_ConstraintsSizeResolver$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_CrossfadePainter$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_CrossfadePainter$stableprop_getter|coil3_compose_CrossfadePainter$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_ImagePainter$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_ImagePainter$stableprop_getter|coil3_compose_ImagePainter$stableprop_getter(){}[0]
final fun coil3.compose/rememberAsyncImagePainter(kotlin/Any?, coil3/ImageLoader, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui.layout/ContentScale?, androidx.compose.ui.graphics/FilterQuality, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): coil3.compose/AsyncImagePainter // coil3.compose/rememberAsyncImagePainter|rememberAsyncImagePainter(kotlin.Any?;coil3.ImageLoader;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.layout.ContentScale?;androidx.compose.ui.graphics.FilterQuality;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/rememberAsyncImagePainter(kotlin/Any?, coil3/ImageLoader, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui.layout/ContentScale?, androidx.compose.ui.graphics/FilterQuality?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): coil3.compose/AsyncImagePainter // coil3.compose/rememberAsyncImagePainter|rememberAsyncImagePainter(kotlin.Any?;coil3.ImageLoader;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.layout.ContentScale?;androidx.compose.ui.graphics.FilterQuality?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/rememberAsyncImagePainter(kotlin/Any?, coil3/ImageLoader, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui.layout/ContentScale?, androidx.compose.ui.graphics/FilterQuality, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): coil3.compose/AsyncImagePainter // coil3.compose/rememberAsyncImagePainter|rememberAsyncImagePainter(kotlin.Any?;coil3.ImageLoader;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.layout.ContentScale?;androidx.compose.ui.graphics.FilterQuality;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/rememberAsyncImagePainter(kotlin/Any?, coil3/ImageLoader, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui.layout/ContentScale?, androidx.compose.ui.graphics/FilterQuality?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): coil3.compose/AsyncImagePainter // coil3.compose/rememberAsyncImagePainter|rememberAsyncImagePainter(kotlin.Any?;coil3.ImageLoader;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.layout.ContentScale?;androidx.compose.ui.graphics.FilterQuality?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/rememberConstraintsSizeResolver(androidx.compose.runtime/Composer?, kotlin/Int): coil3.compose/ConstraintsSizeResolver // coil3.compose/rememberConstraintsSizeResolver|rememberConstraintsSizeResolver(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun coil3.compose/rememberDrawScopeSizeResolver(androidx.compose.runtime/Composer?, kotlin/Int): coil3.compose/DrawScopeSizeResolver // coil3.compose/rememberDrawScopeSizeResolver|rememberDrawScopeSizeResolver(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final inline fun coil3.compose/AsyncImagePreviewHandler(crossinline kotlin.coroutines/SuspendFunction1<coil3.request/ImageRequest, coil3/Image>): coil3.compose/AsyncImagePreviewHandler // coil3.compose/AsyncImagePreviewHandler|AsyncImagePreviewHandler(kotlin.coroutines.SuspendFunction1<coil3.request.ImageRequest,coil3.Image>){}[0]
final inline fun coil3.compose/AsyncImagePreviewHandler(crossinline kotlin.coroutines/SuspendFunction1<coil3.request/ImageRequest, coil3/Image?>): coil3.compose/AsyncImagePreviewHandler // coil3.compose/AsyncImagePreviewHandler|AsyncImagePreviewHandler(kotlin.coroutines.SuspendFunction1<coil3.request.ImageRequest,coil3.Image?>){}[0]
+69
View File
@@ -0,0 +1,69 @@
// :coil:coil-compose-core - AsyncImage / rememberAsyncImagePainter internals, vendored
// VERBATIM from coil-kt/coil. Upstream publishes NO desktop-native klibs for the
// compose layer at all (neither mingwX64 nor linux), so this whole module exists to
// give the port its targets. Compose coords substitute to the port's project modules
// on every native configuration (root build's commonization bridge).
plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.kotlin.plugin.compose)
}
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
kotlin {
linuxArm64(); linuxX64(); macosArm64(); if (vHostSupportsMingw) mingwX64()
applyDefaultHierarchyTemplate()
sourceSets {
commonMain {
dependencies {
api(project(":coil:coil-core"))
// Declared DIRECTLY, not leaned on transitively: these coords are
// SUBSTITUTED to the port's project modules on native configurations,
// and KGP's granular-metadata visibility rule then drops the substituted
// module's transitives from the commonMain metadata classpath (CLAUDE.md
// "Common pitfalls"). Every artifact the vendored common code touches
// needs its own declaration + its own bridge rule.
api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}")
api("org.jetbrains.compose.ui:ui:${libs.versions.compose.get()}")
api("org.jetbrains.compose.ui:ui-graphics:${libs.versions.compose.get()}")
api("org.jetbrains.compose.ui:ui-text:${libs.versions.compose.get()}")
api("org.jetbrains.compose.ui:ui-unit:${libs.versions.compose.get()}")
api("org.jetbrains.compose.ui:ui-geometry:${libs.versions.compose.get()}")
api("org.jetbrains.compose.ui:ui-util:${libs.versions.compose.get()}")
api("org.jetbrains.compose.foundation:foundation:${libs.versions.compose.get()}")
api("org.jetbrains.compose.foundation:foundation-layout:${libs.versions.compose.get()}")
}
kotlin.srcDir("src/vendor/common/kotlin")
}
// Upstream's nonAndroid compose layer reaches straight into org.jetbrains.skia
// (Canvas / Bitmap.asComposeImageBitmap), so it needs skiko on its own compile
// classpath - official for macOS/Linux, the bitsycore FORK for mingwX64, on two
// PARALLEL branches. See coil/coil-core/build.gradle.kts.
fun nonAndroidBranch(inName: String, inSkiko: Any) = create("${inName}NonAndroidMain") {
dependsOn(commonMain.get())
kotlin.srcDir("src/vendor/nonAndroid/kotlin")
dependencies { implementation(inSkiko) }
}
val vOfficial = nonAndroidBranch("coilComposeOfficial", libs.skiko)
get("macosArm64Main").dependsOn(vOfficial)
get("linuxX64Main").dependsOn(vOfficial)
get("linuxArm64Main").dependsOn(vOfficial)
if (vHostSupportsMingw) {
val vFork = nonAndroidBranch(
"coilComposeFork",
"com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse(libs.versions.skikoMingw.get())}",
)
get("mingwX64Main").dependsOn(vFork)
}
}
compilerOptions {
freeCompilerArgs.addAll(
"-Xexpect-actual-classes",
"-opt-in=coil3.annotation.InternalCoilApi",
"-opt-in=coil3.annotation.ExperimentalCoilApi",
"-opt-in=coil3.annotation.DelicateCoilApi",
)
}
}
+44
View File
@@ -0,0 +1,44 @@
# :coil:coil-compose-core - AsyncImage / rememberAsyncImagePainter internals.
# Upstream publishes NEITHER mingwX64 NOR linux for the compose layer.
# Upstream source sets collapse onto this port: it has NO android, jvm or js
# target, so nonAndroidMain / nonJvmCommonMain / nonJsCommonMain / nativeMain all
# apply to EVERY target here. They land in TWO trees, not one: the non* sets keep
# their own level (src/vendor/nonAndroid) ABOVE src/vendor/native, because some of
# them declare `expect`s whose `actual`s live in upstream nativeMain - collapsing
# both into one source set makes expect and actual siblings, which is an error. appleMain is macosArm64
# only and nonAppleMain is linux + mingw, so those two keep their own trees (the
# build file wires a `nonAppleMain` intermediate; appleMain comes from the default
# hierarchy template).
SET_REPO=https://github.com/coil-kt/coil@<COIL_REF>
SET_FOLDER=coil-compose-core/src
commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/coil3/compose/AsyncImage.kt -> src/vendor/common/kotlin/coil3/compose/AsyncImage.kt
# | commonMain/kotlin/coil3/compose/AsyncImagePainter.kt -> src/vendor/common/kotlin/coil3/compose/AsyncImagePainter.kt
# | commonMain/kotlin/coil3/compose/ConstraintsSizeResolver.kt -> src/vendor/common/kotlin/coil3/compose/ConstraintsSizeResolver.kt
# | commonMain/kotlin/coil3/compose/CrossfadePainter.kt -> src/vendor/common/kotlin/coil3/compose/CrossfadePainter.kt
# | commonMain/kotlin/coil3/compose/DrawScopeSizeResolver.kt -> src/vendor/common/kotlin/coil3/compose/DrawScopeSizeResolver.kt
# | commonMain/kotlin/coil3/compose/ImagePainter.kt -> src/vendor/common/kotlin/coil3/compose/ImagePainter.kt
# | commonMain/kotlin/coil3/compose/LocalAsyncImageModelEqualityDelegate.kt -> src/vendor/common/kotlin/coil3/compose/LocalAsyncImageModelEqualityDelegate.kt
# | commonMain/kotlin/coil3/compose/LocalAsyncImagePreviewHandler.kt -> src/vendor/common/kotlin/coil3/compose/LocalAsyncImagePreviewHandler.kt
# | commonMain/kotlin/coil3/compose/LocalPlatformContext.kt -> src/vendor/common/kotlin/coil3/compose/LocalPlatformContext.kt
# | commonMain/kotlin/coil3/compose/SubcomposeAsyncImage.kt -> src/vendor/common/kotlin/coil3/compose/SubcomposeAsyncImage.kt
# | commonMain/kotlin/coil3/compose/imageRequests.kt -> src/vendor/common/kotlin/coil3/compose/imageRequests.kt
# | commonMain/kotlin/coil3/compose/internal/ContentPainterModifier.kt -> src/vendor/common/kotlin/coil3/compose/internal/ContentPainterModifier.kt
# | commonMain/kotlin/coil3/compose/internal/DeferredDispatch.kt -> src/vendor/common/kotlin/coil3/compose/internal/DeferredDispatch.kt
# | commonMain/kotlin/coil3/compose/internal/ForwardingCoroutineContext.kt -> src/vendor/common/kotlin/coil3/compose/internal/ForwardingCoroutineContext.kt
# | commonMain/kotlin/coil3/compose/internal/utils.kt -> src/vendor/common/kotlin/coil3/compose/internal/utils.kt
nonAndroidMain/kotlin/ -> src/vendor/nonAndroid/kotlin/
# | nonAndroidMain/kotlin/coil3/compose/AsyncImagePainter.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/compose/AsyncImagePainter.nonAndroid.kt
# | nonAndroidMain/kotlin/coil3/compose/ImagePainter.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/compose/ImagePainter.nonAndroid.kt
# | nonAndroidMain/kotlin/coil3/compose/LocalPlatformContext.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/compose/LocalPlatformContext.nonAndroid.kt
# | nonAndroidMain/kotlin/coil3/compose/internal/utils.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/compose/internal/utils.nonAndroid.kt
# >>> ---- DIAGNOSTIC GAPS ---- <<<<
# androidMain (4)
# | androidMain/kotlin/coil3/compose/AsyncImagePainter.android.kt -> src/vendor/android/kotlin/coil3/compose/AsyncImagePainter.android.kt
# | androidMain/kotlin/coil3/compose/ImagePainter.android.kt -> src/vendor/android/kotlin/coil3/compose/ImagePainter.android.kt
# | androidMain/kotlin/coil3/compose/LocalPlatformContext.android.kt -> src/vendor/android/kotlin/coil3/compose/LocalPlatformContext.android.kt
# | androidMain/kotlin/coil3/compose/internal/utils.android.kt -> src/vendor/android/kotlin/coil3/compose/internal/utils.android.kt
# <<< ---- DIAGNOSTIC GAPS ---- >>>>
@@ -0,0 +1,21 @@
// 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.coil3:coil-compose>
final fun coil3.compose/AsyncImage(kotlin/Any?, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/AsyncImage|AsyncImage(kotlin.Any?;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/AsyncImage(kotlin/Any?, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality?, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/AsyncImage|AsyncImage(kotlin.Any?;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality?;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/AsyncImage(kotlin/Any?, kotlin/String?, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/AsyncImage|AsyncImage(kotlin.Any?;kotlin.String?;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/AsyncImage(kotlin/Any?, kotlin/String?, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality?, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/AsyncImage|AsyncImage(kotlin.Any?;kotlin.String?;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality?;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/SubcomposeAsyncImage(kotlin/Any?, kotlin/String?, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, kotlin/Boolean, kotlin/Function3<coil3.compose/SubcomposeAsyncImageScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/SubcomposeAsyncImage|SubcomposeAsyncImage(kotlin.Any?;kotlin.String?;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;kotlin.Boolean;kotlin.Function3<coil3.compose.SubcomposeAsyncImageScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/SubcomposeAsyncImage(kotlin/Any?, kotlin/String?, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality?, kotlin/Boolean, kotlin/Function3<coil3.compose/SubcomposeAsyncImageScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/SubcomposeAsyncImage|SubcomposeAsyncImage(kotlin.Any?;kotlin.String?;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality?;kotlin.Boolean;kotlin.Function3<coil3.compose.SubcomposeAsyncImageScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/SubcomposeAsyncImage(kotlin/Any?, kotlin/String?, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Loading, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Success, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Error, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/SubcomposeAsyncImage|SubcomposeAsyncImage(kotlin.Any?;kotlin.String?;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Loading,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Success,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Error,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/SubcomposeAsyncImage(kotlin/Any?, kotlin/String?, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Loading, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Success, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function4<coil3.compose/SubcomposeAsyncImageScope, coil3.compose/AsyncImagePainter.State.Error, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality?, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/SubcomposeAsyncImage|SubcomposeAsyncImage(kotlin.Any?;kotlin.String?;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Loading,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Success,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function4<coil3.compose.SubcomposeAsyncImageScope,coil3.compose.AsyncImagePainter.State.Error,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality?;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/rememberAsyncImagePainter(kotlin/Any?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui.layout/ContentScale?, androidx.compose.ui.graphics/FilterQuality, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): coil3.compose/AsyncImagePainter // coil3.compose/rememberAsyncImagePainter|rememberAsyncImagePainter(kotlin.Any?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.layout.ContentScale?;androidx.compose.ui.graphics.FilterQuality;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/rememberAsyncImagePainter(kotlin/Any?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui.layout/ContentScale?, androidx.compose.ui.graphics/FilterQuality?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): coil3.compose/AsyncImagePainter // coil3.compose/rememberAsyncImagePainter|rememberAsyncImagePainter(kotlin.Any?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.layout.ContentScale?;androidx.compose.ui.graphics.FilterQuality?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/rememberAsyncImagePainter(kotlin/Any?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui.layout/ContentScale?, androidx.compose.ui.graphics/FilterQuality, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): coil3.compose/AsyncImagePainter // coil3.compose/rememberAsyncImagePainter|rememberAsyncImagePainter(kotlin.Any?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.layout.ContentScale?;androidx.compose.ui.graphics.FilterQuality;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/rememberAsyncImagePainter(kotlin/Any?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui.layout/ContentScale?, androidx.compose.ui.graphics/FilterQuality?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): coil3.compose/AsyncImagePainter // coil3.compose/rememberAsyncImagePainter|rememberAsyncImagePainter(kotlin.Any?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.layout.ContentScale?;androidx.compose.ui.graphics.FilterQuality?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/setSingletonImageLoaderFactory(kotlin/Function1<coil3/PlatformContext, coil3/ImageLoader>, androidx.compose.runtime/Composer?, kotlin/Int) // coil3.compose/setSingletonImageLoaderFactory|setSingletonImageLoaderFactory(kotlin.Function1<coil3.PlatformContext,coil3.ImageLoader>;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
+31
View File
@@ -0,0 +1,31 @@
// :coil:coil-compose - the public compose entry points (AsyncImage, SubcomposeAsyncImage),
// vendored VERBATIM from coil-kt/coil. commonMain only. Upstream publishes no
// desktop-native klibs for the compose layer.
plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.kotlin.plugin.compose)
}
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
kotlin {
linuxArm64(); linuxX64(); macosArm64(); if (vHostSupportsMingw) mingwX64()
applyDefaultHierarchyTemplate()
sourceSets {
commonMain {
dependencies {
api(project(":coil:coil"))
api(project(":coil:coil-compose-core"))
}
kotlin.srcDir("src/vendor/common/kotlin")
}
}
compilerOptions {
freeCompilerArgs.addAll(
"-Xexpect-actual-classes",
"-opt-in=coil3.annotation.InternalCoilApi",
"-opt-in=coil3.annotation.ExperimentalCoilApi",
"-opt-in=coil3.annotation.DelicateCoilApi",
)
}
}
+15
View File
@@ -0,0 +1,15 @@
# :coil:coil-compose - the public compose entry points. commonMain only.
# Upstream publishes NEITHER mingwX64 NOR linux for the compose layer.
SET_REPO=https://github.com/coil-kt/coil@<COIL_REF>
SET_FOLDER=coil-compose/src
commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/coil3/compose/SingletonAsyncImage.kt -> src/vendor/common/kotlin/coil3/compose/SingletonAsyncImage.kt
# | commonMain/kotlin/coil3/compose/SingletonAsyncImagePainter.kt -> src/vendor/common/kotlin/coil3/compose/SingletonAsyncImagePainter.kt
# | commonMain/kotlin/coil3/compose/SingletonSubcomposeAsyncImage.kt -> src/vendor/common/kotlin/coil3/compose/SingletonSubcomposeAsyncImage.kt
# | commonMain/kotlin/coil3/compose/singletonImageLoaders.kt -> src/vendor/common/kotlin/coil3/compose/singletonImageLoaders.kt
# >>> ---- DIAGNOSTIC GAPS ---- <<<<
# (none - every source set under SET_FOLDER is vendored)
# <<< ---- DIAGNOSTIC GAPS ---- >>>>
File diff suppressed because it is too large Load Diff
+90
View File
@@ -0,0 +1,90 @@
// :coil:coil-core - coil3.* core, vendored VERBATIM from coil-kt/coil into src/vendor.
//
// Upstream publishes linux + apple klibs but NOT mingwX64, and the code is
// target-agnostic, so the port mostly just re-declares the targets.
//
// SOURCE-SET COLLAPSE: this module has no android, jvm or js target, so upstream's
// nonAndroidMain / nonJvmCommonMain / nonJsCommonMain / nativeMain all apply to every
// target here and are vendored into ONE tree (src/vendor/native). Only the
// apple-vs-rest split survives: appleMain is macosArm64, nonAppleMain is linux+mingw.
//
// SKIA: upstream's non-android decoder is skiko-based (SkiaImageDecoder), which is
// this port's renderer already. macOS/Linux take the official skiko; mingwX64 takes
// the bitsycore FORK, the same swap :compose:ui:ui-graphics makes.
//
// Provenance = compose-fork.txt + scripts/compose-fork/compose.properties. Never
// hand-edit src/vendor - change the manifest + re-run
// `python scripts/compose-fork/sync.py coil/coil-core`.
plugins {
alias(libs.plugins.kotlin.multiplatform)
}
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
kotlin {
linuxArm64(); linuxX64(); macosArm64(); if (vHostSupportsMingw) mingwX64()
applyDefaultHierarchyTemplate()
sourceSets {
commonMain {
dependencies {
api(libs.kotlinx.coroutines.core)
api(libs.okio)
}
kotlin.srcDir("src/vendor/common/kotlin")
}
// SKIKO BRANCHES. Upstream's nonAndroid files use org.jetbrains.skia.*, so the
// intermediate source set that holds them needs skiko on its own compile
// classpath (the shared-metadata compilation is a real compile). macOS/Linux
// take the OFFICIAL skiko; mingwX64 takes the bitsycore FORK - and the two
// cannot share an intermediate, so mingw gets a PARALLEL branch over the same
// srcDirs. Same shape as :compose:ui:ui-graphics.
//
// Each branch is two levels deep because upstream's nonAndroid sets declare
// `expect`s whose `actual`s live in nativeMain - siblings in one set is an error.
fun skikoBranch(inName: String, inSkiko: Any): org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet {
val vNonAndroid = create("${inName}NonAndroidMain") {
dependsOn(commonMain.get())
kotlin.srcDir("src/vendor/nonAndroid/kotlin")
dependencies { implementation(inSkiko) }
}
return create("${inName}NativeMain") {
dependsOn(vNonAndroid)
kotlin.srcDir("src/vendor/native/kotlin")
}
}
val vOfficial = skikoBranch("coilOfficial", libs.skiko)
val vAppleMain = create("coilAppleMain") {
dependsOn(vOfficial)
kotlin.srcDir("src/vendor/apple/kotlin")
}
val vLinuxMain = create("coilLinuxMain") {
dependsOn(vOfficial)
kotlin.srcDir("src/vendor/nonApple/kotlin")
}
get("macosArm64Main").dependsOn(vAppleMain)
get("linuxX64Main").dependsOn(vLinuxMain)
get("linuxArm64Main").dependsOn(vLinuxMain)
if (vHostSupportsMingw) {
val vFork = skikoBranch(
"coilFork",
"com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse(libs.versions.skikoMingw.get())}",
)
val vMingwMain = create("coilMingwMain") {
dependsOn(vFork)
kotlin.srcDir("src/vendor/nonApple/kotlin")
}
get("mingwX64Main").dependsOn(vMingwMain)
}
}
compilerOptions {
freeCompilerArgs.addAll(
"-Xexpect-actual-classes",
"-opt-in=kotlinx.cinterop.ExperimentalForeignApi",
"-opt-in=coil3.annotation.InternalCoilApi",
"-opt-in=coil3.annotation.ExperimentalCoilApi",
"-opt-in=coil3.annotation.DelicateCoilApi",
)
}
}
+206
View File
@@ -0,0 +1,206 @@
# :coil:coil-core - coil3.* core, vendored verbatim from coil-kt/coil.
# Upstream publishes linux + apple but NOT mingwX64, so the port re-declares the
# targets and rebuilds the same sources. Decoding is Skia-based upstream
# (SkiaImageDecoder), which is exactly this port's renderer - on mingwX64 the
# skiko dependency is the bitsycore FORK, as in :compose:ui:ui-graphics.
# Upstream source sets collapse onto this port: it has NO android, jvm or js
# target, so nonAndroidMain / nonJvmCommonMain / nonJsCommonMain / nativeMain all
# apply to EVERY target here. They land in TWO trees, not one: the non* sets keep
# their own level (src/vendor/nonAndroid) ABOVE src/vendor/native, because some of
# them declare `expect`s whose `actual`s live in upstream nativeMain - collapsing
# both into one source set makes expect and actual siblings, which is an error. appleMain is macosArm64
# only and nonAppleMain is linux + mingw, so those two keep their own trees (the
# build file wires a `nonAppleMain` intermediate; appleMain comes from the default
# hierarchy template).
SET_REPO=https://github.com/coil-kt/coil@<COIL_REF>
SET_FOLDER=coil-core/src
commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/coil3/ColorImage.kt -> src/vendor/common/kotlin/coil3/ColorImage.kt
# | commonMain/kotlin/coil3/ComponentRegistry.kt -> src/vendor/common/kotlin/coil3/ComponentRegistry.kt
# | commonMain/kotlin/coil3/EventListener.kt -> src/vendor/common/kotlin/coil3/EventListener.kt
# | commonMain/kotlin/coil3/Extras.kt -> src/vendor/common/kotlin/coil3/Extras.kt
# | commonMain/kotlin/coil3/Image.kt -> src/vendor/common/kotlin/coil3/Image.kt
# | commonMain/kotlin/coil3/ImageLoader.kt -> src/vendor/common/kotlin/coil3/ImageLoader.kt
# | commonMain/kotlin/coil3/PlatformContext.kt -> src/vendor/common/kotlin/coil3/PlatformContext.kt
# | commonMain/kotlin/coil3/RealImageLoader.kt -> src/vendor/common/kotlin/coil3/RealImageLoader.kt
# | commonMain/kotlin/coil3/Uri.kt -> src/vendor/common/kotlin/coil3/Uri.kt
# | commonMain/kotlin/coil3/annotation/annotations.kt -> src/vendor/common/kotlin/coil3/annotation/annotations.kt
# | commonMain/kotlin/coil3/decode/BlackholeDecoder.kt -> src/vendor/common/kotlin/coil3/decode/BlackholeDecoder.kt
# | commonMain/kotlin/coil3/decode/DataSource.kt -> src/vendor/common/kotlin/coil3/decode/DataSource.kt
# | commonMain/kotlin/coil3/decode/DecodeResult.kt -> src/vendor/common/kotlin/coil3/decode/DecodeResult.kt
# | commonMain/kotlin/coil3/decode/DecodeUtils.kt -> src/vendor/common/kotlin/coil3/decode/DecodeUtils.kt
# | commonMain/kotlin/coil3/decode/Decoder.kt -> src/vendor/common/kotlin/coil3/decode/Decoder.kt
# | commonMain/kotlin/coil3/decode/ImageSource.kt -> src/vendor/common/kotlin/coil3/decode/ImageSource.kt
# | commonMain/kotlin/coil3/disk/DiskCache.kt -> src/vendor/common/kotlin/coil3/disk/DiskCache.kt
# | commonMain/kotlin/coil3/disk/DiskLruCache.kt -> src/vendor/common/kotlin/coil3/disk/DiskLruCache.kt
# | commonMain/kotlin/coil3/disk/FaultHidingSink.kt -> src/vendor/common/kotlin/coil3/disk/FaultHidingSink.kt
# | commonMain/kotlin/coil3/disk/RealDiskCache.kt -> src/vendor/common/kotlin/coil3/disk/RealDiskCache.kt
# | commonMain/kotlin/coil3/disk/utils.kt -> src/vendor/common/kotlin/coil3/disk/utils.kt
# | commonMain/kotlin/coil3/fetch/BitmapFetcher.kt -> src/vendor/common/kotlin/coil3/fetch/BitmapFetcher.kt
# | commonMain/kotlin/coil3/fetch/ByteArrayFetcher.kt -> src/vendor/common/kotlin/coil3/fetch/ByteArrayFetcher.kt
# | commonMain/kotlin/coil3/fetch/DataUriFetcher.kt -> src/vendor/common/kotlin/coil3/fetch/DataUriFetcher.kt
# | commonMain/kotlin/coil3/fetch/FetchResult.kt -> src/vendor/common/kotlin/coil3/fetch/FetchResult.kt
# | commonMain/kotlin/coil3/fetch/Fetcher.kt -> src/vendor/common/kotlin/coil3/fetch/Fetcher.kt
# | commonMain/kotlin/coil3/fetch/FileUriFetcher.kt -> src/vendor/common/kotlin/coil3/fetch/FileUriFetcher.kt
# | commonMain/kotlin/coil3/imageLoaders.kt -> src/vendor/common/kotlin/coil3/imageLoaders.kt
# | commonMain/kotlin/coil3/intercept/EngineInterceptor.kt -> src/vendor/common/kotlin/coil3/intercept/EngineInterceptor.kt
# | commonMain/kotlin/coil3/intercept/Interceptor.kt -> src/vendor/common/kotlin/coil3/intercept/Interceptor.kt
# | commonMain/kotlin/coil3/intercept/RealInterceptorChain.kt -> src/vendor/common/kotlin/coil3/intercept/RealInterceptorChain.kt
# | commonMain/kotlin/coil3/key/FileUriKeyer.kt -> src/vendor/common/kotlin/coil3/key/FileUriKeyer.kt
# | commonMain/kotlin/coil3/key/Keyer.kt -> src/vendor/common/kotlin/coil3/key/Keyer.kt
# | commonMain/kotlin/coil3/key/UriKeyer.kt -> src/vendor/common/kotlin/coil3/key/UriKeyer.kt
# | commonMain/kotlin/coil3/map/Mapper.kt -> src/vendor/common/kotlin/coil3/map/Mapper.kt
# | commonMain/kotlin/coil3/map/PathMapper.kt -> src/vendor/common/kotlin/coil3/map/PathMapper.kt
# | commonMain/kotlin/coil3/map/StringMapper.kt -> src/vendor/common/kotlin/coil3/map/StringMapper.kt
# | commonMain/kotlin/coil3/memory/MemoryCache.kt -> src/vendor/common/kotlin/coil3/memory/MemoryCache.kt
# | commonMain/kotlin/coil3/memory/MemoryCacheService.kt -> src/vendor/common/kotlin/coil3/memory/MemoryCacheService.kt
# | commonMain/kotlin/coil3/memory/RealMemoryCache.kt -> src/vendor/common/kotlin/coil3/memory/RealMemoryCache.kt
# | commonMain/kotlin/coil3/memory/StrongMemoryCache.kt -> src/vendor/common/kotlin/coil3/memory/StrongMemoryCache.kt
# | commonMain/kotlin/coil3/memory/WeakMemoryCache.kt -> src/vendor/common/kotlin/coil3/memory/WeakMemoryCache.kt
# | commonMain/kotlin/coil3/request/CachePolicy.kt -> src/vendor/common/kotlin/coil3/request/CachePolicy.kt
# | commonMain/kotlin/coil3/request/Disposable.kt -> src/vendor/common/kotlin/coil3/request/Disposable.kt
# | commonMain/kotlin/coil3/request/ImageRequest.kt -> src/vendor/common/kotlin/coil3/request/ImageRequest.kt
# | commonMain/kotlin/coil3/request/ImageResult.kt -> src/vendor/common/kotlin/coil3/request/ImageResult.kt
# | commonMain/kotlin/coil3/request/NullRequestData.kt -> src/vendor/common/kotlin/coil3/request/NullRequestData.kt
# | commonMain/kotlin/coil3/request/NullRequestDataException.kt -> src/vendor/common/kotlin/coil3/request/NullRequestDataException.kt
# | commonMain/kotlin/coil3/request/Options.kt -> src/vendor/common/kotlin/coil3/request/Options.kt
# | commonMain/kotlin/coil3/request/RequestDelegate.kt -> src/vendor/common/kotlin/coil3/request/RequestDelegate.kt
# | commonMain/kotlin/coil3/request/RequestService.kt -> src/vendor/common/kotlin/coil3/request/RequestService.kt
# | commonMain/kotlin/coil3/request/imageRequests.kt -> src/vendor/common/kotlin/coil3/request/imageRequests.kt
# | commonMain/kotlin/coil3/size/Dimension.kt -> src/vendor/common/kotlin/coil3/size/Dimension.kt
# | commonMain/kotlin/coil3/size/Precision.kt -> src/vendor/common/kotlin/coil3/size/Precision.kt
# | commonMain/kotlin/coil3/size/RealSizeResolver.kt -> src/vendor/common/kotlin/coil3/size/RealSizeResolver.kt
# | commonMain/kotlin/coil3/size/Scale.kt -> src/vendor/common/kotlin/coil3/size/Scale.kt
# | commonMain/kotlin/coil3/size/Size.kt -> src/vendor/common/kotlin/coil3/size/Size.kt
# | commonMain/kotlin/coil3/size/SizeResolver.kt -> src/vendor/common/kotlin/coil3/size/SizeResolver.kt
# | commonMain/kotlin/coil3/target/Target.kt -> src/vendor/common/kotlin/coil3/target/Target.kt
# | commonMain/kotlin/coil3/transform/Transformation.kt -> src/vendor/common/kotlin/coil3/transform/Transformation.kt
# | commonMain/kotlin/coil3/util/LruCache.kt -> src/vendor/common/kotlin/coil3/util/LruCache.kt
# | commonMain/kotlin/coil3/util/ServiceLoaderComponentRegistry.kt -> src/vendor/common/kotlin/coil3/util/ServiceLoaderComponentRegistry.kt
# | commonMain/kotlin/coil3/util/SystemCallbacks.kt -> src/vendor/common/kotlin/coil3/util/SystemCallbacks.kt
# | commonMain/kotlin/coil3/util/collections.kt -> src/vendor/common/kotlin/coil3/util/collections.kt
# | commonMain/kotlin/coil3/util/contexts.kt -> src/vendor/common/kotlin/coil3/util/contexts.kt
# | commonMain/kotlin/coil3/util/coroutines.kt -> src/vendor/common/kotlin/coil3/util/coroutines.kt
# | commonMain/kotlin/coil3/util/fileSystems.kt -> src/vendor/common/kotlin/coil3/util/fileSystems.kt
# | commonMain/kotlin/coil3/util/logging.kt -> src/vendor/common/kotlin/coil3/util/logging.kt
# | commonMain/kotlin/coil3/util/mimeTypes.kt -> src/vendor/common/kotlin/coil3/util/mimeTypes.kt
# | commonMain/kotlin/coil3/util/utils.kt -> src/vendor/common/kotlin/coil3/util/utils.kt
nonAndroidMain/kotlin/ -> src/vendor/nonAndroid/kotlin/
# | nonAndroidMain/kotlin/coil3/ColorImage.kt -> src/vendor/nonAndroid/kotlin/coil3/ColorImage.kt
# | nonAndroidMain/kotlin/coil3/EventListener.kt -> src/vendor/nonAndroid/kotlin/coil3/EventListener.kt
# | nonAndroidMain/kotlin/coil3/Image.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/Image.nonAndroid.kt
# | nonAndroidMain/kotlin/coil3/PlatformContext.kt -> src/vendor/nonAndroid/kotlin/coil3/PlatformContext.kt
# | nonAndroidMain/kotlin/coil3/RealImageLoader.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/RealImageLoader.nonAndroid.kt
# | nonAndroidMain/kotlin/coil3/decode/SkiaImageDecoder.kt -> src/vendor/nonAndroid/kotlin/coil3/decode/SkiaImageDecoder.kt
# | nonAndroidMain/kotlin/coil3/intercept/EngineInterceptor.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/intercept/EngineInterceptor.nonAndroid.kt
# | nonAndroidMain/kotlin/coil3/request/RequestService.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/request/RequestService.nonAndroid.kt
# | nonAndroidMain/kotlin/coil3/request/imageRequests.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/request/imageRequests.nonAndroid.kt
# | nonAndroidMain/kotlin/coil3/util/SystemCallbacks.kt -> src/vendor/nonAndroid/kotlin/coil3/util/SystemCallbacks.kt
# | nonAndroidMain/kotlin/coil3/util/contexts.kt -> src/vendor/nonAndroid/kotlin/coil3/util/contexts.kt
# | nonAndroidMain/kotlin/coil3/util/mimeTypes.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/util/mimeTypes.nonAndroid.kt
# | nonAndroidMain/kotlin/coil3/util/utils.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/util/utils.nonAndroid.kt
nonJvmCommonMain/kotlin/ -> src/vendor/nonAndroid/kotlin/
# | nonJvmCommonMain/kotlin/coil3/RealImageLoader.nonJvmCommon.kt -> src/vendor/nonAndroid/kotlin/coil3/RealImageLoader.nonJvmCommon.kt
# | nonJvmCommonMain/kotlin/coil3/util/ServiceLoaderComponentRegistry.kt -> src/vendor/nonAndroid/kotlin/coil3/util/ServiceLoaderComponentRegistry.kt
# | nonJvmCommonMain/kotlin/coil3/util/collections.nonJvmCommon.kt -> src/vendor/nonAndroid/kotlin/coil3/util/collections.nonJvmCommon.kt
# | nonJvmCommonMain/kotlin/coil3/util/contexts.nonJvmCommon.kt -> src/vendor/nonAndroid/kotlin/coil3/util/contexts.nonJvmCommon.kt
# | nonJvmCommonMain/kotlin/coil3/util/fileSystems.nonJvmCommon.kt -> src/vendor/nonAndroid/kotlin/coil3/util/fileSystems.nonJvmCommon.kt
nonJsCommonMain/kotlin/ -> src/vendor/nonAndroid/kotlin/
# | nonJsCommonMain/kotlin/coil3/disk/utils.kt -> src/vendor/nonAndroid/kotlin/coil3/disk/utils.kt
# | nonJsCommonMain/kotlin/coil3/imageLoaders.nonJsCommon.kt -> src/vendor/nonAndroid/kotlin/coil3/imageLoaders.nonJsCommon.kt
# | nonJsCommonMain/kotlin/coil3/util/coroutines.nonJsCommon.kt -> src/vendor/nonAndroid/kotlin/coil3/util/coroutines.nonJsCommon.kt
# | nonJsCommonMain/kotlin/coil3/util/fileSystems.nonJsCommon.kt -> src/vendor/nonAndroid/kotlin/coil3/util/fileSystems.nonJsCommon.kt
nativeMain/kotlin/ -> src/vendor/native/kotlin/
# | nativeMain/kotlin/coil3/decode/SkiaImageDecoder.native.kt -> src/vendor/native/kotlin/coil3/decode/SkiaImageDecoder.native.kt
# | nativeMain/kotlin/coil3/util/utils.native.kt -> src/vendor/native/kotlin/coil3/util/utils.native.kt
appleMain/kotlin/ -> src/vendor/apple/kotlin/
# | appleMain/kotlin/coil3/RealImageLoader.apple.kt -> src/vendor/apple/kotlin/coil3/RealImageLoader.apple.kt
# | appleMain/kotlin/coil3/map/NSURLMapper.kt -> src/vendor/apple/kotlin/coil3/map/NSURLMapper.kt
nonAppleMain/kotlin/ -> src/vendor/nonApple/kotlin/
# | nonAppleMain/kotlin/coil3/RealImageLoader.nonApple.kt -> src/vendor/nonApple/kotlin/coil3/RealImageLoader.nonApple.kt
# >>> ---- DIAGNOSTIC GAPS ---- <<<<
# androidMain (49)
# | androidMain/kotlin/coil3/ColorImage.kt -> src/vendor/android/kotlin/coil3/ColorImage.kt
# | androidMain/kotlin/coil3/EventListener.kt -> src/vendor/android/kotlin/coil3/EventListener.kt
# | androidMain/kotlin/coil3/Image.android.kt -> src/vendor/android/kotlin/coil3/Image.android.kt
# | androidMain/kotlin/coil3/PlatformContext.kt -> src/vendor/android/kotlin/coil3/PlatformContext.kt
# | androidMain/kotlin/coil3/RealImageLoader.android.kt -> src/vendor/android/kotlin/coil3/RealImageLoader.android.kt
# | androidMain/kotlin/coil3/Uri.android.kt -> src/vendor/android/kotlin/coil3/Uri.android.kt
# | androidMain/kotlin/coil3/decode/BitmapFactoryDecoder.kt -> src/vendor/android/kotlin/coil3/decode/BitmapFactoryDecoder.kt
# | androidMain/kotlin/coil3/decode/ExifOrientationStrategy.kt -> src/vendor/android/kotlin/coil3/decode/ExifOrientationStrategy.kt
# | androidMain/kotlin/coil3/decode/ExifUtils.kt -> src/vendor/android/kotlin/coil3/decode/ExifUtils.kt
# | androidMain/kotlin/coil3/decode/ImageSource.kt -> src/vendor/android/kotlin/coil3/decode/ImageSource.kt
# | androidMain/kotlin/coil3/decode/StaticImageDecoder.kt -> src/vendor/android/kotlin/coil3/decode/StaticImageDecoder.kt
# | androidMain/kotlin/coil3/fetch/AssetUriFetcher.kt -> src/vendor/android/kotlin/coil3/fetch/AssetUriFetcher.kt
# | androidMain/kotlin/coil3/fetch/ContentUriFetcher.kt -> src/vendor/android/kotlin/coil3/fetch/ContentUriFetcher.kt
# | androidMain/kotlin/coil3/fetch/DrawableFetcher.kt -> src/vendor/android/kotlin/coil3/fetch/DrawableFetcher.kt
# | androidMain/kotlin/coil3/fetch/ResourceUriFetcher.kt -> src/vendor/android/kotlin/coil3/fetch/ResourceUriFetcher.kt
# | androidMain/kotlin/coil3/imageLoaders.android.kt -> src/vendor/android/kotlin/coil3/imageLoaders.android.kt
# | androidMain/kotlin/coil3/intercept/EngineInterceptor.android.kt -> src/vendor/android/kotlin/coil3/intercept/EngineInterceptor.android.kt
# | androidMain/kotlin/coil3/key/AndroidResourceUriKeyer.kt -> src/vendor/android/kotlin/coil3/key/AndroidResourceUriKeyer.kt
# | androidMain/kotlin/coil3/map/AndroidUriMapper.kt -> src/vendor/android/kotlin/coil3/map/AndroidUriMapper.kt
# | androidMain/kotlin/coil3/map/ResourceIntMapper.kt -> src/vendor/android/kotlin/coil3/map/ResourceIntMapper.kt
# | androidMain/kotlin/coil3/request/RequestDelegate.android.kt -> src/vendor/android/kotlin/coil3/request/RequestDelegate.android.kt
# | androidMain/kotlin/coil3/request/RequestService.android.kt -> src/vendor/android/kotlin/coil3/request/RequestService.android.kt
# | androidMain/kotlin/coil3/request/ViewTargetDisposable.kt -> src/vendor/android/kotlin/coil3/request/ViewTargetDisposable.kt
# | androidMain/kotlin/coil3/request/ViewTargetRequestManager.kt -> src/vendor/android/kotlin/coil3/request/ViewTargetRequestManager.kt
# | androidMain/kotlin/coil3/request/imageRequests.android.kt -> src/vendor/android/kotlin/coil3/request/imageRequests.android.kt
# | androidMain/kotlin/coil3/size/RealViewSizeResolver.kt -> src/vendor/android/kotlin/coil3/size/RealViewSizeResolver.kt
# | androidMain/kotlin/coil3/size/ScaleDrawable.kt -> src/vendor/android/kotlin/coil3/size/ScaleDrawable.kt
# | androidMain/kotlin/coil3/size/ViewSizeResolver.kt -> src/vendor/android/kotlin/coil3/size/ViewSizeResolver.kt
# | androidMain/kotlin/coil3/target/GenericViewTarget.kt -> src/vendor/android/kotlin/coil3/target/GenericViewTarget.kt
# | androidMain/kotlin/coil3/target/ImageViewTarget.kt -> src/vendor/android/kotlin/coil3/target/ImageViewTarget.kt
# | androidMain/kotlin/coil3/target/ViewTarget.kt -> src/vendor/android/kotlin/coil3/target/ViewTarget.kt
# | androidMain/kotlin/coil3/transform/CircleCropTransformation.kt -> src/vendor/android/kotlin/coil3/transform/CircleCropTransformation.kt
# | androidMain/kotlin/coil3/transform/RoundedCornersTransformation.kt -> src/vendor/android/kotlin/coil3/transform/RoundedCornersTransformation.kt
# | androidMain/kotlin/coil3/transform/transformations.kt -> src/vendor/android/kotlin/coil3/transform/transformations.kt
# | androidMain/kotlin/coil3/transition/CrossfadeDrawable.kt -> src/vendor/android/kotlin/coil3/transition/CrossfadeDrawable.kt
# | androidMain/kotlin/coil3/transition/CrossfadeTransition.kt -> src/vendor/android/kotlin/coil3/transition/CrossfadeTransition.kt
# | androidMain/kotlin/coil3/transition/NoneTransition.kt -> src/vendor/android/kotlin/coil3/transition/NoneTransition.kt
# | androidMain/kotlin/coil3/transition/Transition.kt -> src/vendor/android/kotlin/coil3/transition/Transition.kt
# | androidMain/kotlin/coil3/transition/TransitionTarget.kt -> src/vendor/android/kotlin/coil3/transition/TransitionTarget.kt
# | androidMain/kotlin/coil3/util/CoilUtils.kt -> src/vendor/android/kotlin/coil3/util/CoilUtils.kt
# | androidMain/kotlin/coil3/util/DrawableUtils.kt -> src/vendor/android/kotlin/coil3/util/DrawableUtils.kt
# | androidMain/kotlin/coil3/util/SystemCallbacks.kt -> src/vendor/android/kotlin/coil3/util/SystemCallbacks.kt
# | androidMain/kotlin/coil3/util/bitmaps.kt -> src/vendor/android/kotlin/coil3/util/bitmaps.kt
# | androidMain/kotlin/coil3/util/contexts.kt -> src/vendor/android/kotlin/coil3/util/contexts.kt
# | androidMain/kotlin/coil3/util/fileSystems.android.kt -> src/vendor/android/kotlin/coil3/util/fileSystems.android.kt
# | androidMain/kotlin/coil3/util/hardwareBitmaps.kt -> src/vendor/android/kotlin/coil3/util/hardwareBitmaps.kt
# | androidMain/kotlin/coil3/util/lifecycles.kt -> src/vendor/android/kotlin/coil3/util/lifecycles.kt
# | androidMain/kotlin/coil3/util/mimeTypes.android.kt -> src/vendor/android/kotlin/coil3/util/mimeTypes.android.kt
# | androidMain/kotlin/coil3/util/utils.android.kt -> src/vendor/android/kotlin/coil3/util/utils.android.kt
# jsCommonMain (7)
# | jsCommonMain/kotlin/coil3/decode/SkiaImageDecoder.jsCommon.kt -> src/vendor/jsCommon/kotlin/coil3/decode/SkiaImageDecoder.jsCommon.kt
# | jsCommonMain/kotlin/coil3/decode/WebWorker.kt -> src/vendor/jsCommon/kotlin/coil3/decode/WebWorker.kt
# | jsCommonMain/kotlin/coil3/disk/utils.kt -> src/vendor/jsCommon/kotlin/coil3/disk/utils.kt
# | jsCommonMain/kotlin/coil3/fetch/BlobUriFetcher.kt -> src/vendor/jsCommon/kotlin/coil3/fetch/BlobUriFetcher.kt
# | jsCommonMain/kotlin/coil3/fetch/internal/BlobUriFetcherServiceLoaderTarget.kt -> src/vendor/jsCommon/kotlin/coil3/fetch/internal/BlobUriFetcherServiceLoaderTarget.kt
# | jsCommonMain/kotlin/coil3/util/coroutines.kt -> src/vendor/jsCommon/kotlin/coil3/util/coroutines.kt
# | jsCommonMain/kotlin/coil3/util/fileSystems.kt -> src/vendor/jsCommon/kotlin/coil3/util/fileSystems.kt
# jsMain (3)
# | jsMain/kotlin/coil3/fetch/BlobUriFetcher.js.kt -> src/vendor/js/kotlin/coil3/fetch/BlobUriFetcher.js.kt
# | jsMain/kotlin/coil3/fetch/internal/BlobUriFetcherServiceLoaderTarget.js.kt -> src/vendor/js/kotlin/coil3/fetch/internal/BlobUriFetcherServiceLoaderTarget.js.kt
# | jsMain/kotlin/coil3/util/utils.js.kt -> src/vendor/js/kotlin/coil3/util/utils.js.kt
# jvmCommonMain (10)
# | jvmCommonMain/kotlin/coil3/RealImageLoader.jvmCommon.kt -> src/vendor/jvmCommon/kotlin/coil3/RealImageLoader.jvmCommon.kt
# | jvmCommonMain/kotlin/coil3/decode/ImageSource.kt -> src/vendor/jvmCommon/kotlin/coil3/decode/ImageSource.kt
# | jvmCommonMain/kotlin/coil3/disk/diskCache.kt -> src/vendor/jvmCommon/kotlin/coil3/disk/diskCache.kt
# | jvmCommonMain/kotlin/coil3/fetch/ByteBufferFetcher.kt -> src/vendor/jvmCommon/kotlin/coil3/fetch/ByteBufferFetcher.kt
# | jvmCommonMain/kotlin/coil3/fetch/JarFileFetcher.kt -> src/vendor/jvmCommon/kotlin/coil3/fetch/JarFileFetcher.kt
# | jvmCommonMain/kotlin/coil3/imageLoaders.hidden.kt -> src/vendor/jvmCommon/kotlin/coil3/imageLoaders.hidden.kt
# | jvmCommonMain/kotlin/coil3/map/FileMapper.kt -> src/vendor/jvmCommon/kotlin/coil3/map/FileMapper.kt
# | jvmCommonMain/kotlin/coil3/util/ServiceLoaderComponentRegistry.kt -> src/vendor/jvmCommon/kotlin/coil3/util/ServiceLoaderComponentRegistry.kt
# | jvmCommonMain/kotlin/coil3/util/collections.jvmCommon.kt -> src/vendor/jvmCommon/kotlin/coil3/util/collections.jvmCommon.kt
# | jvmCommonMain/kotlin/coil3/util/utils.jvmCommon.kt -> src/vendor/jvmCommon/kotlin/coil3/util/utils.jvmCommon.kt
# jvmMain (3)
# | jvmMain/kotlin/coil3/decode/SkiaImageDecoder.jvm.kt -> src/vendor/jvm/kotlin/coil3/decode/SkiaImageDecoder.jvm.kt
# | jvmMain/kotlin/coil3/util/contexts.jvm.kt -> src/vendor/jvm/kotlin/coil3/util/contexts.jvm.kt
# | jvmMain/kotlin/coil3/util/fileSystems.jvm.kt -> src/vendor/jvm/kotlin/coil3/util/fileSystems.jvm.kt
# wasmJsMain (3)
# | wasmJsMain/kotlin/coil3/fetch/BlobUriFetcher.wasmJs.kt -> src/vendor/wasmJs/kotlin/coil3/fetch/BlobUriFetcher.wasmJs.kt
# | wasmJsMain/kotlin/coil3/fetch/internal/BlobUriFetcherServiceLoaderTarget.wasmJs.kt -> src/vendor/wasmJs/kotlin/coil3/fetch/internal/BlobUriFetcherServiceLoaderTarget.wasmJs.kt
# | wasmJsMain/kotlin/coil3/util/utils.wasmJs.kt -> src/vendor/wasmJs/kotlin/coil3/util/utils.wasmJs.kt
# <<< ---- DIAGNOSTIC GAPS ---- >>>>
@@ -0,0 +1,197 @@
// 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.coil3:coil-network-core>
abstract fun interface coil3.network/ConnectivityChecker { // coil3.network/ConnectivityChecker|null[0]
abstract fun isOnline(): kotlin/Boolean // coil3.network/ConnectivityChecker.isOnline|isOnline(){}[0]
final object Companion { // coil3.network/ConnectivityChecker.Companion|null[0]
final val ONLINE // coil3.network/ConnectivityChecker.Companion.ONLINE|{}ONLINE[0]
final fun <get-ONLINE>(): coil3.network/ConnectivityChecker // coil3.network/ConnectivityChecker.Companion.ONLINE.<get-ONLINE>|<get-ONLINE>(){}[0]
}
}
abstract interface coil3.network/CacheStrategy { // coil3.network/CacheStrategy|null[0]
abstract suspend fun read(coil3.network/NetworkResponse, coil3.network/NetworkRequest, coil3.request/Options): coil3.network/CacheStrategy.ReadResult // coil3.network/CacheStrategy.read|read(coil3.network.NetworkResponse;coil3.network.NetworkRequest;coil3.request.Options){}[0]
abstract suspend fun write(coil3.network/NetworkResponse?, coil3.network/NetworkRequest, coil3.network/NetworkResponse, coil3.request/Options): coil3.network/CacheStrategy.WriteResult // coil3.network/CacheStrategy.write|write(coil3.network.NetworkResponse?;coil3.network.NetworkRequest;coil3.network.NetworkResponse;coil3.request.Options){}[0]
final class ReadResult { // coil3.network/CacheStrategy.ReadResult|null[0]
constructor <init>(coil3.network/NetworkRequest) // coil3.network/CacheStrategy.ReadResult.<init>|<init>(coil3.network.NetworkRequest){}[0]
constructor <init>(coil3.network/NetworkResponse) // coil3.network/CacheStrategy.ReadResult.<init>|<init>(coil3.network.NetworkResponse){}[0]
final val request // coil3.network/CacheStrategy.ReadResult.request|{}request[0]
final fun <get-request>(): coil3.network/NetworkRequest? // coil3.network/CacheStrategy.ReadResult.request.<get-request>|<get-request>(){}[0]
final val response // coil3.network/CacheStrategy.ReadResult.response|{}response[0]
final fun <get-response>(): coil3.network/NetworkResponse? // coil3.network/CacheStrategy.ReadResult.response.<get-response>|<get-response>(){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // coil3.network/CacheStrategy.ReadResult.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // coil3.network/CacheStrategy.ReadResult.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // coil3.network/CacheStrategy.ReadResult.toString|toString(){}[0]
}
final class WriteResult { // coil3.network/CacheStrategy.WriteResult|null[0]
constructor <init>(coil3.network/NetworkResponse) // coil3.network/CacheStrategy.WriteResult.<init>|<init>(coil3.network.NetworkResponse){}[0]
final val response // coil3.network/CacheStrategy.WriteResult.response|{}response[0]
final fun <get-response>(): coil3.network/NetworkResponse? // coil3.network/CacheStrategy.WriteResult.response.<get-response>|<get-response>(){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // coil3.network/CacheStrategy.WriteResult.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // coil3.network/CacheStrategy.WriteResult.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // coil3.network/CacheStrategy.WriteResult.toString|toString(){}[0]
final object Companion { // coil3.network/CacheStrategy.WriteResult.Companion|null[0]
final val DISABLED // coil3.network/CacheStrategy.WriteResult.Companion.DISABLED|{}DISABLED[0]
final fun <get-DISABLED>(): coil3.network/CacheStrategy.WriteResult // coil3.network/CacheStrategy.WriteResult.Companion.DISABLED.<get-DISABLED>|<get-DISABLED>(){}[0]
}
}
final object Companion { // coil3.network/CacheStrategy.Companion|null[0]
final val DEFAULT // coil3.network/CacheStrategy.Companion.DEFAULT|{}DEFAULT[0]
final fun <get-DEFAULT>(): coil3.network/CacheStrategy // coil3.network/CacheStrategy.Companion.DEFAULT.<get-DEFAULT>|<get-DEFAULT>(){}[0]
}
}
abstract interface coil3.network/ConcurrentRequestStrategy { // coil3.network/ConcurrentRequestStrategy|null[0]
abstract suspend fun apply(kotlin/String, kotlin.coroutines/SuspendFunction0<coil3.fetch/FetchResult>): coil3.fetch/FetchResult // coil3.network/ConcurrentRequestStrategy.apply|apply(kotlin.String;kotlin.coroutines.SuspendFunction0<coil3.fetch.FetchResult>){}[0]
final object Companion { // coil3.network/ConcurrentRequestStrategy.Companion|null[0]
final val UNCOORDINATED // coil3.network/ConcurrentRequestStrategy.Companion.UNCOORDINATED|{}UNCOORDINATED[0]
final fun <get-UNCOORDINATED>(): coil3.network/ConcurrentRequestStrategy // coil3.network/ConcurrentRequestStrategy.Companion.UNCOORDINATED.<get-UNCOORDINATED>|<get-UNCOORDINATED>(){}[0]
}
}
abstract interface coil3.network/NetworkClient { // coil3.network/NetworkClient|null[0]
abstract suspend fun <#A1: kotlin/Any?> executeRequest(coil3.network/NetworkRequest, kotlin.coroutines/SuspendFunction1<coil3.network/NetworkResponse, #A1>): #A1 // coil3.network/NetworkClient.executeRequest|executeRequest(coil3.network.NetworkRequest;kotlin.coroutines.SuspendFunction1<coil3.network.NetworkResponse,0:0>){0§<kotlin.Any?>}[0]
}
abstract interface coil3.network/NetworkRequestBody { // coil3.network/NetworkRequestBody|null[0]
abstract suspend fun writeTo(okio/BufferedSink) // coil3.network/NetworkRequestBody.writeTo|writeTo(okio.BufferedSink){}[0]
}
abstract interface coil3.network/NetworkResponseBody : kotlin/AutoCloseable { // coil3.network/NetworkResponseBody|null[0]
abstract suspend fun writeTo(okio/BufferedSink) // coil3.network/NetworkResponseBody.writeTo|writeTo(okio.BufferedSink){}[0]
abstract suspend fun writeTo(okio/FileSystem, okio/Path) // coil3.network/NetworkResponseBody.writeTo|writeTo(okio.FileSystem;okio.Path){}[0]
}
final class coil3.network/DeDupeConcurrentRequestStrategy : coil3.network/ConcurrentRequestStrategy { // coil3.network/DeDupeConcurrentRequestStrategy|null[0]
constructor <init>() // coil3.network/DeDupeConcurrentRequestStrategy.<init>|<init>(){}[0]
final suspend fun apply(kotlin/String, kotlin.coroutines/SuspendFunction0<coil3.fetch/FetchResult>): coil3.fetch/FetchResult // coil3.network/DeDupeConcurrentRequestStrategy.apply|apply(kotlin.String;kotlin.coroutines.SuspendFunction0<coil3.fetch.FetchResult>){}[0]
}
final class coil3.network/HttpException : kotlin/RuntimeException { // coil3.network/HttpException|null[0]
constructor <init>(coil3.network/NetworkResponse) // coil3.network/HttpException.<init>|<init>(coil3.network.NetworkResponse){}[0]
final val response // coil3.network/HttpException.response|{}response[0]
final fun <get-response>(): coil3.network/NetworkResponse // coil3.network/HttpException.response.<get-response>|<get-response>(){}[0]
}
final class coil3.network/NetworkFetcher : coil3.fetch/Fetcher { // coil3.network/NetworkFetcher|null[0]
constructor <init>(kotlin/String, coil3.request/Options, kotlin/Lazy<coil3.network/NetworkClient>, kotlin/Lazy<coil3.disk/DiskCache?>, kotlin/Lazy<coil3.network/CacheStrategy>, coil3.network/ConnectivityChecker) // coil3.network/NetworkFetcher.<init>|<init>(kotlin.String;coil3.request.Options;kotlin.Lazy<coil3.network.NetworkClient>;kotlin.Lazy<coil3.disk.DiskCache?>;kotlin.Lazy<coil3.network.CacheStrategy>;coil3.network.ConnectivityChecker){}[0]
constructor <init>(kotlin/String, coil3.request/Options, kotlin/Lazy<coil3.network/NetworkClient>, kotlin/Lazy<coil3.disk/DiskCache?>, kotlin/Lazy<coil3.network/CacheStrategy>, kotlin/Lazy<coil3.network/ConnectivityChecker>, kotlin/Lazy<coil3.network/ConcurrentRequestStrategy>) // coil3.network/NetworkFetcher.<init>|<init>(kotlin.String;coil3.request.Options;kotlin.Lazy<coil3.network.NetworkClient>;kotlin.Lazy<coil3.disk.DiskCache?>;kotlin.Lazy<coil3.network.CacheStrategy>;kotlin.Lazy<coil3.network.ConnectivityChecker>;kotlin.Lazy<coil3.network.ConcurrentRequestStrategy>){}[0]
final fun getMimeType(kotlin/String, kotlin/String?): kotlin/String? // coil3.network/NetworkFetcher.getMimeType|getMimeType(kotlin.String;kotlin.String?){}[0]
final suspend fun fetch(): coil3.fetch/FetchResult // coil3.network/NetworkFetcher.fetch|fetch(){}[0]
final class Factory : coil3.fetch/Fetcher.Factory<coil3/Uri> { // coil3.network/NetworkFetcher.Factory|null[0]
constructor <init>(kotlin/Function0<coil3.network/NetworkClient>, kotlin/Function0<coil3.network/CacheStrategy> = ..., kotlin/Function1<coil3/PlatformContext, coil3.network/ConnectivityChecker> = ...) // coil3.network/NetworkFetcher.Factory.<init>|<init>(kotlin.Function0<coil3.network.NetworkClient>;kotlin.Function0<coil3.network.CacheStrategy>;kotlin.Function1<coil3.PlatformContext,coil3.network.ConnectivityChecker>){}[0]
constructor <init>(kotlin/Function0<coil3.network/NetworkClient>, kotlin/Function0<coil3.network/CacheStrategy> = ..., kotlin/Function1<coil3/PlatformContext, coil3.network/ConnectivityChecker> = ..., kotlin/Function0<coil3.network/ConcurrentRequestStrategy> = ...) // coil3.network/NetworkFetcher.Factory.<init>|<init>(kotlin.Function0<coil3.network.NetworkClient>;kotlin.Function0<coil3.network.CacheStrategy>;kotlin.Function1<coil3.PlatformContext,coil3.network.ConnectivityChecker>;kotlin.Function0<coil3.network.ConcurrentRequestStrategy>){}[0]
final fun create(coil3/Uri, coil3.request/Options, coil3/ImageLoader): coil3.fetch/Fetcher? // coil3.network/NetworkFetcher.Factory.create|create(coil3.Uri;coil3.request.Options;coil3.ImageLoader){}[0]
}
}
final class coil3.network/NetworkHeaders { // coil3.network/NetworkHeaders|null[0]
final fun asMap(): kotlin.collections/Map<kotlin/String, kotlin.collections/List<kotlin/String>> // coil3.network/NetworkHeaders.asMap|asMap(){}[0]
final fun get(kotlin/String): kotlin/String? // coil3.network/NetworkHeaders.get|get(kotlin.String){}[0]
final fun getAll(kotlin/String): kotlin.collections/List<kotlin/String> // coil3.network/NetworkHeaders.getAll|getAll(kotlin.String){}[0]
final fun newBuilder(): coil3.network/NetworkHeaders.Builder // coil3.network/NetworkHeaders.newBuilder|newBuilder(){}[0]
final class Builder { // coil3.network/NetworkHeaders.Builder|null[0]
constructor <init>() // coil3.network/NetworkHeaders.Builder.<init>|<init>(){}[0]
constructor <init>(coil3.network/NetworkHeaders) // coil3.network/NetworkHeaders.Builder.<init>|<init>(coil3.network.NetworkHeaders){}[0]
final fun add(kotlin/String, kotlin/String): coil3.network/NetworkHeaders.Builder // coil3.network/NetworkHeaders.Builder.add|add(kotlin.String;kotlin.String){}[0]
final fun build(): coil3.network/NetworkHeaders // coil3.network/NetworkHeaders.Builder.build|build(){}[0]
final fun set(kotlin/String, kotlin.collections/List<kotlin/String>): coil3.network/NetworkHeaders.Builder // coil3.network/NetworkHeaders.Builder.set|set(kotlin.String;kotlin.collections.List<kotlin.String>){}[0]
final fun set(kotlin/String, kotlin/String): coil3.network/NetworkHeaders.Builder // coil3.network/NetworkHeaders.Builder.set|set(kotlin.String;kotlin.String){}[0]
}
final object Companion { // coil3.network/NetworkHeaders.Companion|null[0]
final val EMPTY // coil3.network/NetworkHeaders.Companion.EMPTY|{}EMPTY[0]
final fun <get-EMPTY>(): coil3.network/NetworkHeaders // coil3.network/NetworkHeaders.Companion.EMPTY.<get-EMPTY>|<get-EMPTY>(){}[0]
}
}
final class coil3.network/NetworkRequest { // coil3.network/NetworkRequest|null[0]
constructor <init>(kotlin/String, kotlin/String = ..., coil3.network/NetworkHeaders = ..., coil3.network/NetworkRequestBody? = ...) // coil3.network/NetworkRequest.<init>|<init>(kotlin.String;kotlin.String;coil3.network.NetworkHeaders;coil3.network.NetworkRequestBody?){}[0]
constructor <init>(kotlin/String, kotlin/String = ..., coil3.network/NetworkHeaders = ..., coil3.network/NetworkRequestBody? = ..., coil3/Extras = ...) // coil3.network/NetworkRequest.<init>|<init>(kotlin.String;kotlin.String;coil3.network.NetworkHeaders;coil3.network.NetworkRequestBody?;coil3.Extras){}[0]
final val body // coil3.network/NetworkRequest.body|{}body[0]
final fun <get-body>(): coil3.network/NetworkRequestBody? // coil3.network/NetworkRequest.body.<get-body>|<get-body>(){}[0]
final val extras // coil3.network/NetworkRequest.extras|{}extras[0]
final fun <get-extras>(): coil3/Extras // coil3.network/NetworkRequest.extras.<get-extras>|<get-extras>(){}[0]
final val headers // coil3.network/NetworkRequest.headers|{}headers[0]
final fun <get-headers>(): coil3.network/NetworkHeaders // coil3.network/NetworkRequest.headers.<get-headers>|<get-headers>(){}[0]
final val method // coil3.network/NetworkRequest.method|{}method[0]
final fun <get-method>(): kotlin/String // coil3.network/NetworkRequest.method.<get-method>|<get-method>(){}[0]
final val url // coil3.network/NetworkRequest.url|{}url[0]
final fun <get-url>(): kotlin/String // coil3.network/NetworkRequest.url.<get-url>|<get-url>(){}[0]
final fun copy(kotlin/String = ..., kotlin/String = ..., coil3.network/NetworkHeaders = ..., coil3.network/NetworkRequestBody? = ...): coil3.network/NetworkRequest // coil3.network/NetworkRequest.copy|copy(kotlin.String;kotlin.String;coil3.network.NetworkHeaders;coil3.network.NetworkRequestBody?){}[0]
final fun copy(kotlin/String = ..., kotlin/String = ..., coil3.network/NetworkHeaders = ..., coil3.network/NetworkRequestBody? = ..., coil3/Extras = ...): coil3.network/NetworkRequest // coil3.network/NetworkRequest.copy|copy(kotlin.String;kotlin.String;coil3.network.NetworkHeaders;coil3.network.NetworkRequestBody?;coil3.Extras){}[0]
}
final class coil3.network/NetworkResponse { // coil3.network/NetworkResponse|null[0]
constructor <init>(kotlin/Int = ..., kotlin/Long = ..., kotlin/Long = ..., coil3.network/NetworkHeaders = ..., coil3.network/NetworkResponseBody? = ..., kotlin/Any? = ...) // coil3.network/NetworkResponse.<init>|<init>(kotlin.Int;kotlin.Long;kotlin.Long;coil3.network.NetworkHeaders;coil3.network.NetworkResponseBody?;kotlin.Any?){}[0]
final val body // coil3.network/NetworkResponse.body|{}body[0]
final fun <get-body>(): coil3.network/NetworkResponseBody? // coil3.network/NetworkResponse.body.<get-body>|<get-body>(){}[0]
final val code // coil3.network/NetworkResponse.code|{}code[0]
final fun <get-code>(): kotlin/Int // coil3.network/NetworkResponse.code.<get-code>|<get-code>(){}[0]
final val delegate // coil3.network/NetworkResponse.delegate|{}delegate[0]
final fun <get-delegate>(): kotlin/Any? // coil3.network/NetworkResponse.delegate.<get-delegate>|<get-delegate>(){}[0]
final val headers // coil3.network/NetworkResponse.headers|{}headers[0]
final fun <get-headers>(): coil3.network/NetworkHeaders // coil3.network/NetworkResponse.headers.<get-headers>|<get-headers>(){}[0]
final val requestMillis // coil3.network/NetworkResponse.requestMillis|{}requestMillis[0]
final fun <get-requestMillis>(): kotlin/Long // coil3.network/NetworkResponse.requestMillis.<get-requestMillis>|<get-requestMillis>(){}[0]
final val responseMillis // coil3.network/NetworkResponse.responseMillis|{}responseMillis[0]
final fun <get-responseMillis>(): kotlin/Long // coil3.network/NetworkResponse.responseMillis.<get-responseMillis>|<get-responseMillis>(){}[0]
final fun copy(kotlin/Int = ..., kotlin/Long = ..., kotlin/Long = ..., coil3.network/NetworkHeaders = ..., coil3.network/NetworkResponseBody? = ..., kotlin/Any? = ...): coil3.network/NetworkResponse // coil3.network/NetworkResponse.copy|copy(kotlin.Int;kotlin.Long;kotlin.Long;coil3.network.NetworkHeaders;coil3.network.NetworkResponseBody?;kotlin.Any?){}[0]
}
final object coil3.network/CacheNetworkResponse { // coil3.network/CacheNetworkResponse|null[0]
final fun readFrom(okio/BufferedSource): coil3.network/NetworkResponse // coil3.network/CacheNetworkResponse.readFrom|readFrom(okio.BufferedSource){}[0]
final fun writeTo(coil3.network/NetworkResponse, okio/BufferedSink) // coil3.network/CacheNetworkResponse.writeTo|writeTo(coil3.network.NetworkResponse;okio.BufferedSink){}[0]
}
final val coil3.network/httpBody // coil3.network/httpBody|@coil3.Extras.Key.Companion{}httpBody[0]
final fun (coil3/Extras.Key.Companion).<get-httpBody>(): coil3/Extras.Key<coil3.network/NetworkRequestBody?> // coil3.network/httpBody.<get-httpBody>|<get-httpBody>@coil3.Extras.Key.Companion(){}[0]
final val coil3.network/httpBody // coil3.network/httpBody|@coil3.request.ImageRequest{}httpBody[0]
final fun (coil3.request/ImageRequest).<get-httpBody>(): coil3.network/NetworkRequestBody? // coil3.network/httpBody.<get-httpBody>|<get-httpBody>@coil3.request.ImageRequest(){}[0]
final val coil3.network/httpBody // coil3.network/httpBody|@coil3.request.Options{}httpBody[0]
final fun (coil3.request/Options).<get-httpBody>(): coil3.network/NetworkRequestBody? // coil3.network/httpBody.<get-httpBody>|<get-httpBody>@coil3.request.Options(){}[0]
final val coil3.network/httpHeaders // coil3.network/httpHeaders|@coil3.Extras.Key.Companion{}httpHeaders[0]
final fun (coil3/Extras.Key.Companion).<get-httpHeaders>(): coil3/Extras.Key<coil3.network/NetworkHeaders> // coil3.network/httpHeaders.<get-httpHeaders>|<get-httpHeaders>@coil3.Extras.Key.Companion(){}[0]
final val coil3.network/httpHeaders // coil3.network/httpHeaders|@coil3.request.ImageRequest{}httpHeaders[0]
final fun (coil3.request/ImageRequest).<get-httpHeaders>(): coil3.network/NetworkHeaders // coil3.network/httpHeaders.<get-httpHeaders>|<get-httpHeaders>@coil3.request.ImageRequest(){}[0]
final val coil3.network/httpHeaders // coil3.network/httpHeaders|@coil3.request.Options{}httpHeaders[0]
final fun (coil3.request/Options).<get-httpHeaders>(): coil3.network/NetworkHeaders // coil3.network/httpHeaders.<get-httpHeaders>|<get-httpHeaders>@coil3.request.Options(){}[0]
final val coil3.network/httpMethod // coil3.network/httpMethod|@coil3.Extras.Key.Companion{}httpMethod[0]
final fun (coil3/Extras.Key.Companion).<get-httpMethod>(): coil3/Extras.Key<kotlin/String> // coil3.network/httpMethod.<get-httpMethod>|<get-httpMethod>@coil3.Extras.Key.Companion(){}[0]
final val coil3.network/httpMethod // coil3.network/httpMethod|@coil3.request.ImageRequest{}httpMethod[0]
final fun (coil3.request/ImageRequest).<get-httpMethod>(): kotlin/String // coil3.network/httpMethod.<get-httpMethod>|<get-httpMethod>@coil3.request.ImageRequest(){}[0]
final val coil3.network/httpMethod // coil3.network/httpMethod|@coil3.request.Options{}httpMethod[0]
final fun (coil3.request/Options).<get-httpMethod>(): kotlin/String // coil3.network/httpMethod.<get-httpMethod>|<get-httpMethod>@coil3.request.Options(){}[0]
final fun (coil3.request/ImageRequest.Builder).coil3.network/httpBody(coil3.network/NetworkRequestBody): coil3.request/ImageRequest.Builder // coil3.network/httpBody|httpBody@coil3.request.ImageRequest.Builder(coil3.network.NetworkRequestBody){}[0]
final fun (coil3.request/ImageRequest.Builder).coil3.network/httpHeaders(coil3.network/NetworkHeaders): coil3.request/ImageRequest.Builder // coil3.network/httpHeaders|httpHeaders@coil3.request.ImageRequest.Builder(coil3.network.NetworkHeaders){}[0]
final fun (coil3.request/ImageRequest.Builder).coil3.network/httpMethod(kotlin/String): coil3.request/ImageRequest.Builder // coil3.network/httpMethod|httpMethod@coil3.request.ImageRequest.Builder(kotlin.String){}[0]
final fun coil3.network/ConnectivityChecker(coil3/PlatformContext): coil3.network/ConnectivityChecker // coil3.network/ConnectivityChecker|ConnectivityChecker(coil3.PlatformContext){}[0]
final fun coil3.network/NetworkRequestBody(okio/ByteString): coil3.network/NetworkRequestBody // coil3.network/NetworkRequestBody|NetworkRequestBody(okio.ByteString){}[0]
final fun coil3.network/NetworkResponseBody(okio/BufferedSource): coil3.network/NetworkResponseBody // coil3.network/NetworkResponseBody|NetworkResponseBody(okio.BufferedSource){}[0]
+34
View File
@@ -0,0 +1,34 @@
// :coil:coil-network-core - vendored VERBATIM from coil-kt/coil into src/vendor.
// Shared network-fetcher plumbing. Upstream: linux + apple, no mingwX64.
// Upstream's non* source sets sit ABOVE nativeMain here (see coil-core's build file
// and compose-fork.txt for why). Provenance = compose-fork.txt; never hand-edit
// src/vendor - change the manifest + `python scripts/compose-fork/sync.py coil/coil-network-core`.
plugins {
alias(libs.plugins.kotlin.multiplatform)
}
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
kotlin {
linuxArm64(); linuxX64(); macosArm64(); if (vHostSupportsMingw) mingwX64()
applyDefaultHierarchyTemplate()
sourceSets {
commonMain {
dependencies { api(project(":coil:coil-core")) }
kotlin.srcDir("src/vendor/common/kotlin")
}
val vNonAndroidMain = create("coilNonAndroidMain") {
dependsOn(commonMain.get())
kotlin.srcDir("src/vendor/nonAndroid/kotlin")
}
nativeMain { dependsOn(vNonAndroidMain) }
}
compilerOptions {
freeCompilerArgs.addAll(
"-Xexpect-actual-classes",
"-opt-in=coil3.annotation.InternalCoilApi",
"-opt-in=coil3.annotation.ExperimentalCoilApi",
"-opt-in=coil3.annotation.DelicateCoilApi",
)
}
}
+37
View File
@@ -0,0 +1,37 @@
# :coil:coil-network-core - shared network fetcher plumbing.
# Upstream: linux + apple, no mingwX64.
# Upstream source sets collapse onto this port: it has NO android, jvm or js
# target, so nonAndroidMain / nonJvmCommonMain / nonJsCommonMain / nativeMain all
# apply to EVERY target here. They land in TWO trees, not one: the non* sets keep
# their own level (src/vendor/nonAndroid) ABOVE src/vendor/native, because some of
# them declare `expect`s whose `actual`s live in upstream nativeMain - collapsing
# both into one source set makes expect and actual siblings, which is an error. appleMain is macosArm64
# only and nonAppleMain is linux + mingw, so those two keep their own trees (the
# build file wires a `nonAppleMain` intermediate; appleMain comes from the default
# hierarchy template).
SET_REPO=https://github.com/coil-kt/coil@<COIL_REF>
SET_FOLDER=coil-network-core/src
commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/coil3/network/CacheNetworkResponse.kt -> src/vendor/common/kotlin/coil3/network/CacheNetworkResponse.kt
# | commonMain/kotlin/coil3/network/CacheStrategy.kt -> src/vendor/common/kotlin/coil3/network/CacheStrategy.kt
# | commonMain/kotlin/coil3/network/ConcurrentRequestStrategy.kt -> src/vendor/common/kotlin/coil3/network/ConcurrentRequestStrategy.kt
# | commonMain/kotlin/coil3/network/ConnectivityChecker.kt -> src/vendor/common/kotlin/coil3/network/ConnectivityChecker.kt
# | commonMain/kotlin/coil3/network/HttpException.kt -> src/vendor/common/kotlin/coil3/network/HttpException.kt
# | commonMain/kotlin/coil3/network/NetworkClient.kt -> src/vendor/common/kotlin/coil3/network/NetworkClient.kt
# | commonMain/kotlin/coil3/network/NetworkFetcher.kt -> src/vendor/common/kotlin/coil3/network/NetworkFetcher.kt
# | commonMain/kotlin/coil3/network/NetworkHeaders.kt -> src/vendor/common/kotlin/coil3/network/NetworkHeaders.kt
# | commonMain/kotlin/coil3/network/imageRequests.kt -> src/vendor/common/kotlin/coil3/network/imageRequests.kt
# | commonMain/kotlin/coil3/network/internal/DefaultCacheStrategy.kt -> src/vendor/common/kotlin/coil3/network/internal/DefaultCacheStrategy.kt
# | commonMain/kotlin/coil3/network/internal/SingleParameterLazy.kt -> src/vendor/common/kotlin/coil3/network/internal/SingleParameterLazy.kt
# | commonMain/kotlin/coil3/network/internal/utils.kt -> src/vendor/common/kotlin/coil3/network/internal/utils.kt
nonAndroidMain/kotlin/ -> src/vendor/nonAndroid/kotlin/
# | nonAndroidMain/kotlin/coil3/network/ConnectivityChecker.kt -> src/vendor/nonAndroid/kotlin/coil3/network/ConnectivityChecker.kt
# | nonAndroidMain/kotlin/coil3/network/internal/utils.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/network/internal/utils.nonAndroid.kt
# >>> ---- DIAGNOSTIC GAPS ---- <<<<
# androidMain (2)
# | androidMain/kotlin/coil3/network/ConnectivityChecker.kt -> src/vendor/android/kotlin/coil3/network/ConnectivityChecker.kt
# | androidMain/kotlin/coil3/network/internal/utils.android.kt -> src/vendor/android/kotlin/coil3/network/internal/utils.android.kt
# <<< ---- DIAGNOSTIC GAPS ---- >>>>
@@ -0,0 +1,18 @@
// 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.coil3:coil-network-ktor3>
final val coil3.network.ktor3.internal/initHook // coil3.network.ktor3.internal/initHook|{}initHook[0]
final fun <get-initHook>(): kotlin/Any // coil3.network.ktor3.internal/initHook.<get-initHook>|<get-initHook>(){}[0]
final fun (io.ktor.client/HttpClient).coil3.network.ktor3/asNetworkClient(): coil3.network/NetworkClient // coil3.network.ktor3/asNetworkClient|asNetworkClient@io.ktor.client.HttpClient(){}[0]
final fun coil3.network.ktor3/KtorNetworkFetcherFactory(): coil3.network/NetworkFetcher.Factory // coil3.network.ktor3/KtorNetworkFetcherFactory|KtorNetworkFetcherFactory(){}[0]
final fun coil3.network.ktor3/KtorNetworkFetcherFactory(io.ktor.client/HttpClient): coil3.network/NetworkFetcher.Factory // coil3.network.ktor3/KtorNetworkFetcherFactory|KtorNetworkFetcherFactory(io.ktor.client.HttpClient){}[0]
final fun coil3.network.ktor3/KtorNetworkFetcherFactory(io.ktor.client/HttpClient, coil3.network/ConcurrentRequestStrategy = ...): coil3.network/NetworkFetcher.Factory // coil3.network.ktor3/KtorNetworkFetcherFactory|KtorNetworkFetcherFactory(io.ktor.client.HttpClient;coil3.network.ConcurrentRequestStrategy){}[0]
final fun coil3.network.ktor3/KtorNetworkFetcherFactory(kotlin/Function0<io.ktor.client/HttpClient> = ..., kotlin/Function0<coil3.network/CacheStrategy> = ..., kotlin/Function1<coil3/PlatformContext, coil3.network/ConnectivityChecker> = ...): coil3.network/NetworkFetcher.Factory // coil3.network.ktor3/KtorNetworkFetcherFactory|KtorNetworkFetcherFactory(kotlin.Function0<io.ktor.client.HttpClient>;kotlin.Function0<coil3.network.CacheStrategy>;kotlin.Function1<coil3.PlatformContext,coil3.network.ConnectivityChecker>){}[0]
final fun coil3.network.ktor3/KtorNetworkFetcherFactory(kotlin/Function0<io.ktor.client/HttpClient> = ..., kotlin/Function0<coil3.network/CacheStrategy> = ..., kotlin/Function1<coil3/PlatformContext, coil3.network/ConnectivityChecker> = ..., kotlin/Function0<coil3.network/ConcurrentRequestStrategy> = ...): coil3.network/NetworkFetcher.Factory // coil3.network.ktor3/KtorNetworkFetcherFactory|KtorNetworkFetcherFactory(kotlin.Function0<io.ktor.client.HttpClient>;kotlin.Function0<coil3.network.CacheStrategy>;kotlin.Function1<coil3.PlatformContext,coil3.network.ConnectivityChecker>;kotlin.Function0<coil3.network.ConcurrentRequestStrategy>){}[0]
final fun coil3.network.ktor3/KtorNetworkFetcherFactory(kotlin/Function0<io.ktor.client/HttpClient>): coil3.network/NetworkFetcher.Factory // coil3.network.ktor3/KtorNetworkFetcherFactory|KtorNetworkFetcherFactory(kotlin.Function0<io.ktor.client.HttpClient>){}[0]
+42
View File
@@ -0,0 +1,42 @@
// :coil:coil-network-ktor3 - vendored VERBATIM from coil-kt/coil into src/vendor.
// Ktor 3 network fetcher, on the port's existing ktor pin.
// Upstream's non* source sets sit ABOVE nativeMain here (see coil-core's build file
// and compose-fork.txt for why). Provenance = compose-fork.txt; never hand-edit
// src/vendor - change the manifest + `python scripts/compose-fork/sync.py coil/coil-network-ktor3`.
plugins {
alias(libs.plugins.kotlin.multiplatform)
}
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
kotlin {
linuxArm64(); linuxX64(); macosArm64(); if (vHostSupportsMingw) mingwX64()
applyDefaultHierarchyTemplate()
sourceSets {
commonMain {
dependencies {
api(project(":coil:coil-core"))
api(project(":coil:coil-network-core"))
api(libs.ktor.client.core)
}
kotlin.srcDir("src/vendor/common/kotlin")
}
val vNonAndroidMain = create("coilNonAndroidMain") {
dependsOn(commonMain.get())
kotlin.srcDir("src/vendor/nonAndroid/kotlin")
dependencies { implementation(libs.kotlinx.io.okio) }
}
nativeMain {
dependsOn(vNonAndroidMain)
kotlin.srcDir("src/vendor/native/kotlin")
}
}
compilerOptions {
freeCompilerArgs.addAll(
"-Xexpect-actual-classes",
"-opt-in=coil3.annotation.InternalCoilApi",
"-opt-in=coil3.annotation.ExperimentalCoilApi",
"-opt-in=coil3.annotation.DelicateCoilApi",
)
}
}
+32
View File
@@ -0,0 +1,32 @@
# :coil:coil-network-ktor3 - Ktor 3 network fetcher. Upstream: linux + apple, no mingwX64.
# Pairs with the port's existing ktor pin (the `ktor` entry in libs.versions.toml).
# Upstream source sets collapse onto this port: it has NO android, jvm or js
# target, so nonAndroidMain / nonJvmCommonMain / nonJsCommonMain / nativeMain all
# apply to EVERY target here. They land in TWO trees, not one: the non* sets keep
# their own level (src/vendor/nonAndroid) ABOVE src/vendor/native, because some of
# them declare `expect`s whose `actual`s live in upstream nativeMain - collapsing
# both into one source set makes expect and actual siblings, which is an error. appleMain is macosArm64
# only and nonAppleMain is linux + mingw, so those two keep their own trees (the
# build file wires a `nonAppleMain` intermediate; appleMain comes from the default
# hierarchy template).
SET_REPO=https://github.com/coil-kt/coil@<COIL_REF>
SET_FOLDER=coil-network-ktor3/src
commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/coil3/network/ktor3/KtorNetworkFetcher.kt -> src/vendor/common/kotlin/coil3/network/ktor3/KtorNetworkFetcher.kt
# | commonMain/kotlin/coil3/network/ktor3/internal/KtorNetworkFetcherServiceLoaderTarget.kt -> src/vendor/common/kotlin/coil3/network/ktor3/internal/KtorNetworkFetcherServiceLoaderTarget.kt
# | commonMain/kotlin/coil3/network/ktor3/internal/utils.kt -> src/vendor/common/kotlin/coil3/network/ktor3/internal/utils.kt
nonJvmCommonMain/kotlin/ -> src/vendor/nonAndroid/kotlin/
# | nonJvmCommonMain/kotlin/coil3/network/ktor3/internal/utils.nonJvmCommon.kt -> src/vendor/nonAndroid/kotlin/coil3/network/ktor3/internal/utils.nonJvmCommon.kt
nativeMain/kotlin/ -> src/vendor/native/kotlin/
# | nativeMain/kotlin/coil3/network/ktor3/internal/KtorNetworkFetcherServiceLoaderTarget.native.kt -> src/vendor/native/kotlin/coil3/network/ktor3/internal/KtorNetworkFetcherServiceLoaderTarget.native.kt
# >>> ---- DIAGNOSTIC GAPS ---- <<<<
# jsMain (1)
# | jsMain/kotlin/coil3/network/ktor3/internal/KtorNetworkFetcherServiceLoaderTarget.js.kt -> src/vendor/js/kotlin/coil3/network/ktor3/internal/KtorNetworkFetcherServiceLoaderTarget.js.kt
# jvmCommonMain (1)
# | jvmCommonMain/kotlin/coil3/network/ktor3/internal/utils.jvmCommon.kt -> src/vendor/jvmCommon/kotlin/coil3/network/ktor3/internal/utils.jvmCommon.kt
# wasmJsMain (1)
# | wasmJsMain/kotlin/coil3/network/ktor3/internal/KtorNetworkFetcherServiceLoaderTarget.wasmJs.kt -> src/vendor/wasmJs/kotlin/coil3/network/ktor3/internal/KtorNetworkFetcherServiceLoaderTarget.wasmJs.kt
# <<< ---- DIAGNOSTIC GAPS ---- >>>>
+123
View File
@@ -0,0 +1,123 @@
// 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.coil3:coil-svg>
abstract interface coil3.svg/Svg { // coil3.svg/Svg|null[0]
abstract val height // coil3.svg/Svg.height|{}height[0]
abstract fun <get-height>(): kotlin/Float // coil3.svg/Svg.height.<get-height>|<get-height>(){}[0]
abstract val width // coil3.svg/Svg.width|{}width[0]
abstract fun <get-width>(): kotlin/Float // coil3.svg/Svg.width.<get-width>|<get-width>(){}[0]
abstract var viewBox // coil3.svg/Svg.viewBox|{}viewBox[0]
abstract fun <get-viewBox>(): coil3.svg/Svg.ViewBox? // coil3.svg/Svg.viewBox.<get-viewBox>|<get-viewBox>(){}[0]
abstract fun <set-viewBox>(coil3.svg/Svg.ViewBox?) // coil3.svg/Svg.viewBox.<set-viewBox>|<set-viewBox>(coil3.svg.Svg.ViewBox?){}[0]
abstract fun asImage(kotlin/Int = ..., kotlin/Int = ...): coil3/Image // coil3.svg/Svg.asImage|asImage(kotlin.Int;kotlin.Int){}[0]
abstract fun height(kotlin/String) // coil3.svg/Svg.height|height(kotlin.String){}[0]
abstract fun options(coil3.request/Options) // coil3.svg/Svg.options|options(coil3.request.Options){}[0]
abstract fun width(kotlin/String) // coil3.svg/Svg.width|width(kotlin.String){}[0]
abstract fun interface Parser { // coil3.svg/Svg.Parser|null[0]
abstract fun parse(okio/BufferedSource): coil3.svg/Svg // coil3.svg/Svg.Parser.parse|parse(okio.BufferedSource){}[0]
final object Companion { // coil3.svg/Svg.Parser.Companion|null[0]
final val DEFAULT // coil3.svg/Svg.Parser.Companion.DEFAULT|{}DEFAULT[0]
final fun <get-DEFAULT>(): coil3.svg/Svg.Parser // coil3.svg/Svg.Parser.Companion.DEFAULT.<get-DEFAULT>|<get-DEFAULT>(){}[0]
}
}
final class ViewBox { // coil3.svg/Svg.ViewBox|null[0]
constructor <init>(kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float) // coil3.svg/Svg.ViewBox.<init>|<init>(kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float){}[0]
final val bottom // coil3.svg/Svg.ViewBox.bottom|{}bottom[0]
final fun <get-bottom>(): kotlin/Float // coil3.svg/Svg.ViewBox.bottom.<get-bottom>|<get-bottom>(){}[0]
final val left // coil3.svg/Svg.ViewBox.left|{}left[0]
final fun <get-left>(): kotlin/Float // coil3.svg/Svg.ViewBox.left.<get-left>|<get-left>(){}[0]
final val right // coil3.svg/Svg.ViewBox.right|{}right[0]
final fun <get-right>(): kotlin/Float // coil3.svg/Svg.ViewBox.right.<get-right>|<get-right>(){}[0]
final val top // coil3.svg/Svg.ViewBox.top|{}top[0]
final fun <get-top>(): kotlin/Float // coil3.svg/Svg.ViewBox.top.<get-top>|<get-top>(){}[0]
final fun component1(): kotlin/Float // coil3.svg/Svg.ViewBox.component1|component1(){}[0]
final fun component2(): kotlin/Float // coil3.svg/Svg.ViewBox.component2|component2(){}[0]
final fun component3(): kotlin/Float // coil3.svg/Svg.ViewBox.component3|component3(){}[0]
final fun component4(): kotlin/Float // coil3.svg/Svg.ViewBox.component4|component4(){}[0]
final fun copy(kotlin/Float = ..., kotlin/Float = ..., kotlin/Float = ..., kotlin/Float = ...): coil3.svg/Svg.ViewBox // coil3.svg/Svg.ViewBox.copy|copy(kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // coil3.svg/Svg.ViewBox.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // coil3.svg/Svg.ViewBox.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // coil3.svg/Svg.ViewBox.toString|toString(){}[0]
}
}
final class coil3.svg/SvgDecoder : coil3.decode/Decoder { // coil3.svg/SvgDecoder|null[0]
constructor <init>(coil3.decode/ImageSource, coil3.request/Options, coil3.svg/Svg.Parser = ..., kotlin/Function1<coil3/PlatformContext, kotlin/Float> = ..., kotlin/Boolean = ..., kotlin/Boolean = ...) // coil3.svg/SvgDecoder.<init>|<init>(coil3.decode.ImageSource;coil3.request.Options;coil3.svg.Svg.Parser;kotlin.Function1<coil3.PlatformContext,kotlin.Float>;kotlin.Boolean;kotlin.Boolean){}[0]
constructor <init>(coil3.decode/ImageSource, coil3.request/Options, kotlin/Boolean = ..., kotlin/Boolean = ..., kotlin/Boolean = ...) // coil3.svg/SvgDecoder.<init>|<init>(coil3.decode.ImageSource;coil3.request.Options;kotlin.Boolean;kotlin.Boolean;kotlin.Boolean){}[0]
final val density // coil3.svg/SvgDecoder.density|{}density[0]
final fun <get-density>(): kotlin/Function1<coil3/PlatformContext, kotlin/Float> // coil3.svg/SvgDecoder.density.<get-density>|<get-density>(){}[0]
final val parser // coil3.svg/SvgDecoder.parser|{}parser[0]
final fun <get-parser>(): coil3.svg/Svg.Parser // coil3.svg/SvgDecoder.parser.<get-parser>|<get-parser>(){}[0]
final val renderToBitmap // coil3.svg/SvgDecoder.renderToBitmap|{}renderToBitmap[0]
final fun <get-renderToBitmap>(): kotlin/Boolean // coil3.svg/SvgDecoder.renderToBitmap.<get-renderToBitmap>|<get-renderToBitmap>(){}[0]
final val scaleToDensity // coil3.svg/SvgDecoder.scaleToDensity|{}scaleToDensity[0]
final fun <get-scaleToDensity>(): kotlin/Boolean // coil3.svg/SvgDecoder.scaleToDensity.<get-scaleToDensity>|<get-scaleToDensity>(){}[0]
final val useViewBoundsAsIntrinsicSize // coil3.svg/SvgDecoder.useViewBoundsAsIntrinsicSize|{}useViewBoundsAsIntrinsicSize[0]
final fun <get-useViewBoundsAsIntrinsicSize>(): kotlin/Boolean // coil3.svg/SvgDecoder.useViewBoundsAsIntrinsicSize.<get-useViewBoundsAsIntrinsicSize>|<get-useViewBoundsAsIntrinsicSize>(){}[0]
final suspend fun decode(): coil3.decode/DecodeResult // coil3.svg/SvgDecoder.decode|decode(){}[0]
final class Factory : coil3.decode/Decoder.Factory { // coil3.svg/SvgDecoder.Factory|null[0]
constructor <init>(coil3.svg/Svg.Parser = ..., kotlin/Function1<coil3/PlatformContext, kotlin/Float> = ..., kotlin/Boolean = ..., kotlin/Boolean = ...) // coil3.svg/SvgDecoder.Factory.<init>|<init>(coil3.svg.Svg.Parser;kotlin.Function1<coil3.PlatformContext,kotlin.Float>;kotlin.Boolean;kotlin.Boolean){}[0]
constructor <init>(kotlin/Boolean = ..., kotlin/Boolean = ..., kotlin/Boolean = ...) // coil3.svg/SvgDecoder.Factory.<init>|<init>(kotlin.Boolean;kotlin.Boolean;kotlin.Boolean){}[0]
final val density // coil3.svg/SvgDecoder.Factory.density|{}density[0]
final fun <get-density>(): kotlin/Function1<coil3/PlatformContext, kotlin/Float> // coil3.svg/SvgDecoder.Factory.density.<get-density>|<get-density>(){}[0]
final val parser // coil3.svg/SvgDecoder.Factory.parser|{}parser[0]
final fun <get-parser>(): coil3.svg/Svg.Parser // coil3.svg/SvgDecoder.Factory.parser.<get-parser>|<get-parser>(){}[0]
final val renderToBitmap // coil3.svg/SvgDecoder.Factory.renderToBitmap|{}renderToBitmap[0]
final fun <get-renderToBitmap>(): kotlin/Boolean // coil3.svg/SvgDecoder.Factory.renderToBitmap.<get-renderToBitmap>|<get-renderToBitmap>(){}[0]
final val scaleToDensity // coil3.svg/SvgDecoder.Factory.scaleToDensity|{}scaleToDensity[0]
final fun <get-scaleToDensity>(): kotlin/Boolean // coil3.svg/SvgDecoder.Factory.scaleToDensity.<get-scaleToDensity>|<get-scaleToDensity>(){}[0]
final val useViewBoundsAsIntrinsicSize // coil3.svg/SvgDecoder.Factory.useViewBoundsAsIntrinsicSize|{}useViewBoundsAsIntrinsicSize[0]
final fun <get-useViewBoundsAsIntrinsicSize>(): kotlin/Boolean // coil3.svg/SvgDecoder.Factory.useViewBoundsAsIntrinsicSize.<get-useViewBoundsAsIntrinsicSize>|<get-useViewBoundsAsIntrinsicSize>(){}[0]
final fun create(coil3.fetch/SourceFetchResult, coil3.request/Options, coil3/ImageLoader): coil3.decode/Decoder? // coil3.svg/SvgDecoder.Factory.create|create(coil3.fetch.SourceFetchResult;coil3.request.Options;coil3.ImageLoader){}[0]
}
final object Companion { // coil3.svg/SvgDecoder.Companion|null[0]
final val NO_DENSITY // coil3.svg/SvgDecoder.Companion.NO_DENSITY|{}NO_DENSITY[0]
final fun <get-NO_DENSITY>(): kotlin/Function1<coil3/PlatformContext, kotlin/Float> // coil3.svg/SvgDecoder.Companion.NO_DENSITY.<get-NO_DENSITY>|<get-NO_DENSITY>(){}[0]
final val PLATFORM_DENSITY // coil3.svg/SvgDecoder.Companion.PLATFORM_DENSITY|{}PLATFORM_DENSITY[0]
final fun <get-PLATFORM_DENSITY>(): kotlin/Function1<coil3/PlatformContext, kotlin/Float> // coil3.svg/SvgDecoder.Companion.PLATFORM_DENSITY.<get-PLATFORM_DENSITY>|<get-PLATFORM_DENSITY>(){}[0]
}
}
final class coil3.svg/SvgImage : coil3/Image { // coil3.svg/SvgImage|null[0]
constructor <init>(org.jetbrains.skia.svg/SVGDOM, kotlin/Int, kotlin/Int) // coil3.svg/SvgImage.<init>|<init>(org.jetbrains.skia.svg.SVGDOM;kotlin.Int;kotlin.Int){}[0]
final val height // coil3.svg/SvgImage.height|{}height[0]
final fun <get-height>(): kotlin/Int // coil3.svg/SvgImage.height.<get-height>|<get-height>(){}[0]
final val shareable // coil3.svg/SvgImage.shareable|{}shareable[0]
final fun <get-shareable>(): kotlin/Boolean // coil3.svg/SvgImage.shareable.<get-shareable>|<get-shareable>(){}[0]
final val size // coil3.svg/SvgImage.size|{}size[0]
final fun <get-size>(): kotlin/Long // coil3.svg/SvgImage.size.<get-size>|<get-size>(){}[0]
final val svg // coil3.svg/SvgImage.svg|{}svg[0]
final fun <get-svg>(): org.jetbrains.skia.svg/SVGDOM // coil3.svg/SvgImage.svg.<get-svg>|<get-svg>(){}[0]
final val width // coil3.svg/SvgImage.width|{}width[0]
final fun <get-width>(): kotlin/Int // coil3.svg/SvgImage.width.<get-width>|<get-width>(){}[0]
final fun draw(org.jetbrains.skia/Canvas) // coil3.svg/SvgImage.draw|draw(org.jetbrains.skia.Canvas){}[0]
}
final val coil3.svg.internal/initHook // coil3.svg.internal/initHook|{}initHook[0]
final fun <get-initHook>(): kotlin/Any // coil3.svg.internal/initHook.<get-initHook>|<get-initHook>(){}[0]
final val coil3.svg/height // coil3.svg/height|@coil3.svg.Svg.ViewBox{}height[0]
final fun (coil3.svg/Svg.ViewBox).<get-height>(): kotlin/Float // coil3.svg/height.<get-height>|<get-height>@coil3.svg.Svg.ViewBox(){}[0]
final val coil3.svg/width // coil3.svg/width|@coil3.svg.Svg.ViewBox{}width[0]
final fun (coil3.svg/Svg.ViewBox).<get-width>(): kotlin/Float // coil3.svg/width.<get-width>|<get-width>@coil3.svg.Svg.ViewBox(){}[0]
final fun (coil3.decode/DecodeUtils).coil3.svg/isSvg(okio/BufferedSource): kotlin/Boolean // coil3.svg/isSvg|isSvg@coil3.decode.DecodeUtils(okio.BufferedSource){}[0]
+55
View File
@@ -0,0 +1,55 @@
// :coil:coil-svg - SVG decoding, vendored VERBATIM from coil-kt/coil into src/vendor.
// Upstream: linux + apple, no mingwX64. The non-android decoder goes through skiko's
// SVGDOM, so mingwX64 binds the bitsycore skiko FORK like :compose:ui:ui-graphics.
// Upstream's non* source sets sit ABOVE nativeMain here (see coil-core).
plugins {
alias(libs.plugins.kotlin.multiplatform)
}
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
kotlin {
linuxArm64(); linuxX64(); macosArm64(); if (vHostSupportsMingw) mingwX64()
applyDefaultHierarchyTemplate()
sourceSets {
commonMain {
dependencies { api(project(":coil:coil-core")) }
kotlin.srcDir("src/vendor/common/kotlin")
}
// Two PARALLEL skiko branches (official for macOS/Linux, the bitsycore fork for
// mingwX64), each two levels deep so nonAndroid `expect`s and nativeMain
// `actual`s are not siblings. See coil/coil-core/build.gradle.kts for the why.
fun skikoBranch(inName: String, inSkiko: Any): org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet {
val vNonAndroid = create("${inName}NonAndroidMain") {
dependsOn(commonMain.get())
kotlin.srcDir("src/vendor/nonAndroid/kotlin")
dependencies { implementation(inSkiko) }
}
return create("${inName}NativeMain") {
dependsOn(vNonAndroid)
kotlin.srcDir("src/vendor/native/kotlin")
}
}
val vOfficial = skikoBranch("coilSvgOfficial", libs.skiko)
get("macosArm64Main").dependsOn(vOfficial)
get("linuxX64Main").dependsOn(vOfficial)
get("linuxArm64Main").dependsOn(vOfficial)
if (vHostSupportsMingw) {
val vFork = skikoBranch(
"coilSvgFork",
"com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse(libs.versions.skikoMingw.get())}",
)
get("mingwX64Main").dependsOn(vFork)
}
}
compilerOptions {
freeCompilerArgs.addAll(
"-Xexpect-actual-classes",
"-opt-in=coil3.annotation.InternalCoilApi",
"-opt-in=coil3.annotation.ExperimentalCoilApi",
"-opt-in=coil3.annotation.DelicateCoilApi",
)
}
}
+44
View File
@@ -0,0 +1,44 @@
# :coil:coil-svg - SVG decoding. Upstream: linux + apple, no mingwX64.
# The non-android decoder goes through skiko's SVGDOM.
# Upstream source sets collapse onto this port: it has NO android, jvm or js
# target, so nonAndroidMain / nonJvmCommonMain / nonJsCommonMain / nativeMain all
# apply to EVERY target here. They land in TWO trees, not one: the non* sets keep
# their own level (src/vendor/nonAndroid) ABOVE src/vendor/native, because some of
# them declare `expect`s whose `actual`s live in upstream nativeMain - collapsing
# both into one source set makes expect and actual siblings, which is an error. appleMain is macosArm64
# only and nonAppleMain is linux + mingw, so those two keep their own trees (the
# build file wires a `nonAppleMain` intermediate; appleMain comes from the default
# hierarchy template).
SET_REPO=https://github.com/coil-kt/coil@<COIL_REF>
SET_FOLDER=coil-svg/src
commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/coil3/svg/Svg.kt -> src/vendor/common/kotlin/coil3/svg/Svg.kt
# | commonMain/kotlin/coil3/svg/SvgDecoder.kt -> src/vendor/common/kotlin/coil3/svg/SvgDecoder.kt
# | commonMain/kotlin/coil3/svg/decodeUtils.kt -> src/vendor/common/kotlin/coil3/svg/decodeUtils.kt
# | commonMain/kotlin/coil3/svg/internal/SvgDecoderServiceLoaderTarget.kt -> src/vendor/common/kotlin/coil3/svg/internal/SvgDecoderServiceLoaderTarget.kt
# | commonMain/kotlin/coil3/svg/internal/parseSvg.kt -> src/vendor/common/kotlin/coil3/svg/internal/parseSvg.kt
# | commonMain/kotlin/coil3/svg/internal/utils.kt -> src/vendor/common/kotlin/coil3/svg/internal/utils.kt
nonAndroidMain/kotlin/ -> src/vendor/nonAndroid/kotlin/
# | nonAndroidMain/kotlin/coil3/svg/SvgImage.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/svg/SvgImage.nonAndroid.kt
# | nonAndroidMain/kotlin/coil3/svg/internal/parseSvg.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/svg/internal/parseSvg.nonAndroid.kt
# | nonAndroidMain/kotlin/coil3/svg/internal/utils.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/svg/internal/utils.nonAndroid.kt
nonJvmCommonMain/kotlin/ -> src/vendor/nonAndroid/kotlin/
# | nonJvmCommonMain/kotlin/coil3/svg/internal/utils.nonJvmCommon.kt -> src/vendor/nonAndroid/kotlin/coil3/svg/internal/utils.nonJvmCommon.kt
nativeMain/kotlin/ -> src/vendor/native/kotlin/
# | nativeMain/kotlin/coil3/svg/internal/SvgDecoderServiceLoaderTarget.native.kt -> src/vendor/native/kotlin/coil3/svg/internal/SvgDecoderServiceLoaderTarget.native.kt
# >>> ---- DIAGNOSTIC GAPS ---- <<<<
# androidMain (4)
# | androidMain/kotlin/coil3/svg/SvgImage.android.kt -> src/vendor/android/kotlin/coil3/svg/SvgImage.android.kt
# | androidMain/kotlin/coil3/svg/imageRequests.android.kt -> src/vendor/android/kotlin/coil3/svg/imageRequests.android.kt
# | androidMain/kotlin/coil3/svg/internal/parseSvg.android.kt -> src/vendor/android/kotlin/coil3/svg/internal/parseSvg.android.kt
# | androidMain/kotlin/coil3/svg/internal/utils.android.kt -> src/vendor/android/kotlin/coil3/svg/internal/utils.android.kt
# jsMain (1)
# | jsMain/kotlin/coil3/svg/internal/SvgDecoderServiceLoaderTarget.js.kt -> src/vendor/js/kotlin/coil3/svg/internal/SvgDecoderServiceLoaderTarget.js.kt
# jvmCommonMain (1)
# | jvmCommonMain/kotlin/coil3/svg/internal/utils.jvmCommon.kt -> src/vendor/jvmCommon/kotlin/coil3/svg/internal/utils.jvmCommon.kt
# wasmJsMain (1)
# | wasmJsMain/kotlin/coil3/svg/internal/SvgDecoderServiceLoaderTarget.wasmJs.kt -> src/vendor/wasmJs/kotlin/coil3/svg/internal/SvgDecoderServiceLoaderTarget.wasmJs.kt
# <<< ---- DIAGNOSTIC GAPS ---- >>>>
+19
View File
@@ -0,0 +1,19 @@
// 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.coil3:coil>
final object coil3/SingletonImageLoader { // coil3/SingletonImageLoader|null[0]
final fun get(coil3/PlatformContext): coil3/ImageLoader // coil3/SingletonImageLoader.get|get(coil3.PlatformContext){}[0]
final fun reset() // coil3/SingletonImageLoader.reset|reset(){}[0]
final fun setSafe(coil3/SingletonImageLoader.Factory) // coil3/SingletonImageLoader.setSafe|setSafe(coil3.SingletonImageLoader.Factory){}[0]
final fun setUnsafe(coil3/ImageLoader) // coil3/SingletonImageLoader.setUnsafe|setUnsafe(coil3.ImageLoader){}[0]
final fun setUnsafe(coil3/SingletonImageLoader.Factory) // coil3/SingletonImageLoader.setUnsafe|setUnsafe(coil3.SingletonImageLoader.Factory){}[0]
abstract fun interface Factory { // coil3/SingletonImageLoader.Factory|null[0]
abstract fun newImageLoader(coil3/PlatformContext): coil3/ImageLoader // coil3/SingletonImageLoader.Factory.newImageLoader|newImageLoader(coil3.PlatformContext){}[0]
}
}
+34
View File
@@ -0,0 +1,34 @@
// :coil:coil - vendored VERBATIM from coil-kt/coil into src/vendor.
// The singleton ImageLoader facade. Upstream: linux + apple, no mingwX64.
// Upstream's non* source sets sit ABOVE nativeMain here (see coil-core's build file
// and compose-fork.txt for why). Provenance = compose-fork.txt; never hand-edit
// src/vendor - change the manifest + `python scripts/compose-fork/sync.py coil/coil`.
plugins {
alias(libs.plugins.kotlin.multiplatform)
}
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
kotlin {
linuxArm64(); linuxX64(); macosArm64(); if (vHostSupportsMingw) mingwX64()
applyDefaultHierarchyTemplate()
sourceSets {
commonMain {
dependencies { api(project(":coil:coil-core")) }
kotlin.srcDir("src/vendor/common/kotlin")
}
val vNonAndroidMain = create("coilNonAndroidMain") {
dependsOn(commonMain.get())
kotlin.srcDir("src/vendor/nonAndroid/kotlin")
}
nativeMain { dependsOn(vNonAndroidMain) }
}
compilerOptions {
freeCompilerArgs.addAll(
"-Xexpect-actual-classes",
"-opt-in=coil3.annotation.InternalCoilApi",
"-opt-in=coil3.annotation.ExperimentalCoilApi",
"-opt-in=coil3.annotation.DelicateCoilApi",
)
}
}
+24
View File
@@ -0,0 +1,24 @@
# :coil:coil - the singleton ImageLoader facade. Upstream: linux + apple, no mingwX64.
# Upstream source sets collapse onto this port: it has NO android, jvm or js
# target, so nonAndroidMain / nonJvmCommonMain / nonJsCommonMain / nativeMain all
# apply to EVERY target here. They land in TWO trees, not one: the non* sets keep
# their own level (src/vendor/nonAndroid) ABOVE src/vendor/native, because some of
# them declare `expect`s whose `actual`s live in upstream nativeMain - collapsing
# both into one source set makes expect and actual siblings, which is an error. appleMain is macosArm64
# only and nonAppleMain is linux + mingw, so those two keep their own trees (the
# build file wires a `nonAppleMain` intermediate; appleMain comes from the default
# hierarchy template).
SET_REPO=https://github.com/coil-kt/coil@<COIL_REF>
SET_FOLDER=coil/src
commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/coil3/SingletonImageLoader.kt -> src/vendor/common/kotlin/coil3/SingletonImageLoader.kt
nonAndroidMain/kotlin/ -> src/vendor/nonAndroid/kotlin/
# | nonAndroidMain/kotlin/coil3/SingletonImageLoader.nonAndroid.kt -> src/vendor/nonAndroid/kotlin/coil3/SingletonImageLoader.nonAndroid.kt
# >>> ---- DIAGNOSTIC GAPS ---- <<<<
# androidMain (2)
# | androidMain/kotlin/coil3/SingletonImageLoader.android.kt -> src/vendor/android/kotlin/coil3/SingletonImageLoader.android.kt
# | androidMain/kotlin/coil3/singletonImageLoaders.android.kt -> src/vendor/android/kotlin/coil3/singletonImageLoaders.android.kt
# <<< ---- DIAGNOSTIC GAPS ---- >>>>
@@ -34,7 +34,7 @@ kotlin {
// foundation (isSystemInDarkTheme in ResourceEnvironment) pulls the // foundation (isSystemInDarkTheme in ResourceEnvironment) pulls the
// whole ui surface + loadComposeResourceBytes + the sdl3 cinterop // whole ui surface + loadComposeResourceBytes + the sdl3 cinterop
// types transitively (all edges are api). // types transitively (all edges are api).
api(project(":foundation")) api(project(":compose:foundation:foundation"))
implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.coroutines.core)
} }
} }
@@ -1,5 +1,11 @@
@file:OptIn(InternalResourceApi::class, ExperimentalResourceApi::class) @file:OptIn(InternalResourceApi::class, ExperimentalResourceApi::class)
// VENDOR-REIMPL(COMPOSE_REF): components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/FontResources.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package org.jetbrains.compose.resources package org.jetbrains.compose.resources
import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.InternalResourceApi
@@ -1,5 +1,11 @@
@file:OptIn(InternalResourceApi::class, ExperimentalResourceApi::class) @file:OptIn(InternalResourceApi::class, ExperimentalResourceApi::class)
// VENDOR-REIMPL(COMPOSE_REF): components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/ImageResources.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package org.jetbrains.compose.resources package org.jetbrains.compose.resources
import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.InternalResourceApi
@@ -16,7 +16,7 @@ package org.jetbrains.compose.resources.vector.xmldom
CDATA skipping, and the five predefined entities plus numeric character CDATA skipping, and the five predefined entities plus numeric character
references. No DTD expansion, no processing-instruction handling beyond references. No DTD expansion, no processing-instruction handling beyond
skipping - malformed input throws MalformedXMLException like upstream. */ skipping - malformed input throws MalformedXMLException like upstream. */
// VENDOR-BASE(COMPOSE_REF): components/resources/library/src/nativeMain/kotlin/org/jetbrains/compose/resources/vector/xmldom/DomXmlParser.kt @ v1.12.0-beta03+dev4483 // VENDOR-BASE(COMPOSE_REF): components/resources/library/src/nativeMain/kotlin/org/jetbrains/compose/resources/vector/xmldom/DomXmlParser.kt @ v1.12.0
// (fresh REIMPL, not a copy-edit - the base ref marks the upstream API it tracks) // (fresh REIMPL, not a copy-edit - the base ref marks the upstream API it tracks)
internal fun parse(xml: String): Element { internal fun parse(xml: String): Element {
@@ -30,7 +30,7 @@ kotlin {
commonMain { commonMain {
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
dependencies { dependencies {
api(project(":ui")) api(project(":compose:ui:ui"))
} }
} }
nativeMain { nativeMain {
@@ -28,8 +28,8 @@ kotlin {
dependencies { dependencies {
// animation.graphics.* uses animation.* / animation.core.* and the vector // animation.graphics.* uses animation.* / animation.core.* and the vector
// graphics from ui (ui-graphics.vector, ui-util). // graphics from ui (ui-graphics.vector, ui-util).
api(project(":animation")) api(project(":compose:animation:animation"))
api(project(":ui")) api(project(":compose:ui:ui"))
} }
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
} }
+2 -2
View File
@@ -28,8 +28,8 @@ kotlin {
dependencies { dependencies {
// animation.* imports animation.core.* and foundation.layout.* (Box/Row/Column); // animation.* imports animation.core.* and foundation.layout.* (Box/Row/Column);
// ui / runtime arrive transitively. // ui / runtime arrive transitively.
api(project(":animation-core")) api(project(":compose:animation:animation-core"))
api(project(":foundation-layout")) api(project(":compose:foundation:foundation-layout"))
} }
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
} }
@@ -34,12 +34,12 @@ kotlin {
// out of :ui (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(":compose:material3:material3"))`
// themselves (:material3 doesn't need to be `api`-exposed - the // themselves (:material3 doesn't need to be `api`-exposed - the
// upstream vendored surface is stable and apps import it directly). // upstream vendored surface is stable and apps import it directly).
api(project(":ui")) api(project(":compose:ui:ui"))
api(project(":foundation")) api(project(":compose:foundation:foundation"))
api(project(":animation-core")) api(project(":compose:animation:animation-core"))
implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.coroutines.core)
// setMain() / resetMain() - see Sdl3MainDispatcher.kt for usage. // setMain() / resetMain() - see Sdl3MainDispatcher.kt for usage.
implementation(libs.kotlinx.coroutines.test) implementation(libs.kotlinx.coroutines.test)
@@ -27,7 +27,7 @@ kotlin {
commonMain { commonMain {
dependencies { dependencies {
// foundation.layout.* only needs ui (+ runtime/collection transitively). // foundation.layout.* only needs ui (+ runtime/collection transitively).
api(project(":ui")) api(project(":compose:ui:ui"))
} }
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
} }
@@ -778,6 +778,17 @@ abstract interface androidx.compose.foundation.text/TextAutoSize { // androidx.c
} }
} }
abstract interface androidx.compose.foundation.v2/ScrollbarAdapter { // androidx.compose.foundation.v2/ScrollbarAdapter|null[0]
abstract val contentSize // androidx.compose.foundation.v2/ScrollbarAdapter.contentSize|{}contentSize[0]
abstract fun <get-contentSize>(): kotlin/Double // androidx.compose.foundation.v2/ScrollbarAdapter.contentSize.<get-contentSize>|<get-contentSize>(){}[0]
abstract val scrollOffset // androidx.compose.foundation.v2/ScrollbarAdapter.scrollOffset|{}scrollOffset[0]
abstract fun <get-scrollOffset>(): kotlin/Double // androidx.compose.foundation.v2/ScrollbarAdapter.scrollOffset.<get-scrollOffset>|<get-scrollOffset>(){}[0]
abstract val viewportSize // androidx.compose.foundation.v2/ScrollbarAdapter.viewportSize|{}viewportSize[0]
abstract fun <get-viewportSize>(): kotlin/Double // androidx.compose.foundation.v2/ScrollbarAdapter.viewportSize.<get-viewportSize>|<get-viewportSize>(){}[0]
abstract suspend fun scrollTo(kotlin/Double) // androidx.compose.foundation.v2/ScrollbarAdapter.scrollTo|scrollTo(kotlin.Double){}[0]
}
abstract interface androidx.compose.foundation/BasicTooltipState { // androidx.compose.foundation/BasicTooltipState|null[0] abstract interface androidx.compose.foundation/BasicTooltipState { // androidx.compose.foundation/BasicTooltipState|null[0]
abstract val isPersistent // androidx.compose.foundation/BasicTooltipState.isPersistent|{}isPersistent[0] abstract val isPersistent // androidx.compose.foundation/BasicTooltipState.isPersistent|{}isPersistent[0]
abstract fun <get-isPersistent>(): kotlin/Boolean // androidx.compose.foundation/BasicTooltipState.isPersistent.<get-isPersistent>|<get-isPersistent>(){}[0] abstract fun <get-isPersistent>(): kotlin/Boolean // androidx.compose.foundation/BasicTooltipState.isPersistent.<get-isPersistent>|<get-isPersistent>(){}[0]
@@ -830,15 +841,12 @@ abstract interface androidx.compose.foundation/ScrollIndicatorState { // android
abstract fun <get-viewportSize>(): kotlin/Int // androidx.compose.foundation/ScrollIndicatorState.viewportSize.<get-viewportSize>|<get-viewportSize>(){}[0] abstract fun <get-viewportSize>(): kotlin/Int // androidx.compose.foundation/ScrollIndicatorState.viewportSize.<get-viewportSize>|<get-viewportSize>(){}[0]
} }
abstract interface com.compose.sdl.scrollbar/ScrollbarAdapter { // com.compose.sdl.scrollbar/ScrollbarAdapter|null[0] abstract interface androidx.compose.foundation/ScrollbarAdapter { // androidx.compose.foundation/ScrollbarAdapter|null[0]
abstract val contentSize // com.compose.sdl.scrollbar/ScrollbarAdapter.contentSize|{}contentSize[0] abstract val scrollOffset // androidx.compose.foundation/ScrollbarAdapter.scrollOffset|{}scrollOffset[0]
abstract fun <get-contentSize>(): kotlin/Double // com.compose.sdl.scrollbar/ScrollbarAdapter.contentSize.<get-contentSize>|<get-contentSize>(){}[0] abstract fun <get-scrollOffset>(): kotlin/Float // androidx.compose.foundation/ScrollbarAdapter.scrollOffset.<get-scrollOffset>|<get-scrollOffset>(){}[0]
abstract val scrollOffset // com.compose.sdl.scrollbar/ScrollbarAdapter.scrollOffset|{}scrollOffset[0]
abstract fun <get-scrollOffset>(): kotlin/Double // com.compose.sdl.scrollbar/ScrollbarAdapter.scrollOffset.<get-scrollOffset>|<get-scrollOffset>(){}[0]
abstract val viewportSize // com.compose.sdl.scrollbar/ScrollbarAdapter.viewportSize|{}viewportSize[0]
abstract fun <get-viewportSize>(): kotlin/Double // com.compose.sdl.scrollbar/ScrollbarAdapter.viewportSize.<get-viewportSize>|<get-viewportSize>(){}[0]
abstract suspend fun scrollTo(kotlin/Double) // com.compose.sdl.scrollbar/ScrollbarAdapter.scrollTo|scrollTo(kotlin.Double){}[0] abstract fun maxScrollOffset(kotlin/Int): kotlin/Float // androidx.compose.foundation/ScrollbarAdapter.maxScrollOffset|maxScrollOffset(kotlin.Int){}[0]
abstract suspend fun scrollTo(kotlin/Int, kotlin/Float) // androidx.compose.foundation/ScrollbarAdapter.scrollTo|scrollTo(kotlin.Int;kotlin.Float){}[0]
} }
sealed interface <#A: out kotlin/Any?> androidx.compose.foundation.lazy.layout/IntervalList { // androidx.compose.foundation.lazy.layout/IntervalList|null[0] sealed interface <#A: out kotlin/Any?> androidx.compose.foundation.lazy.layout/IntervalList { // androidx.compose.foundation.lazy.layout/IntervalList|null[0]
@@ -1829,21 +1837,32 @@ final class androidx.compose.foundation/ScrollState : androidx.compose.foundatio
} }
} }
final class com.compose.sdl.scrollbar/ScrollbarStyle { // com.compose.sdl.scrollbar/ScrollbarStyle|null[0] final class androidx.compose.foundation/ScrollbarStyle { // androidx.compose.foundation/ScrollbarStyle|null[0]
constructor <init>(androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.graphics/Shape, kotlin/Int, androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color) // com.compose.sdl.scrollbar/ScrollbarStyle.<init>|<init>(androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.graphics.Shape;kotlin.Int;androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color){}[0] constructor <init>(androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.graphics/Shape, kotlin/Int, androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color) // androidx.compose.foundation/ScrollbarStyle.<init>|<init>(androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.graphics.Shape;kotlin.Int;androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color){}[0]
final val hoverColor // com.compose.sdl.scrollbar/ScrollbarStyle.hoverColor|{}hoverColor[0] final val hoverColor // androidx.compose.foundation/ScrollbarStyle.hoverColor|{}hoverColor[0]
final fun <get-hoverColor>(): androidx.compose.ui.graphics/Color // com.compose.sdl.scrollbar/ScrollbarStyle.hoverColor.<get-hoverColor>|<get-hoverColor>(){}[0] final fun <get-hoverColor>(): androidx.compose.ui.graphics/Color // androidx.compose.foundation/ScrollbarStyle.hoverColor.<get-hoverColor>|<get-hoverColor>(){}[0]
final val hoverDurationMillis // com.compose.sdl.scrollbar/ScrollbarStyle.hoverDurationMillis|{}hoverDurationMillis[0] final val hoverDurationMillis // androidx.compose.foundation/ScrollbarStyle.hoverDurationMillis|{}hoverDurationMillis[0]
final fun <get-hoverDurationMillis>(): kotlin/Int // com.compose.sdl.scrollbar/ScrollbarStyle.hoverDurationMillis.<get-hoverDurationMillis>|<get-hoverDurationMillis>(){}[0] final fun <get-hoverDurationMillis>(): kotlin/Int // androidx.compose.foundation/ScrollbarStyle.hoverDurationMillis.<get-hoverDurationMillis>|<get-hoverDurationMillis>(){}[0]
final val minimalHeight // com.compose.sdl.scrollbar/ScrollbarStyle.minimalHeight|{}minimalHeight[0] final val minimalHeight // androidx.compose.foundation/ScrollbarStyle.minimalHeight|{}minimalHeight[0]
final fun <get-minimalHeight>(): androidx.compose.ui.unit/Dp // com.compose.sdl.scrollbar/ScrollbarStyle.minimalHeight.<get-minimalHeight>|<get-minimalHeight>(){}[0] final fun <get-minimalHeight>(): androidx.compose.ui.unit/Dp // androidx.compose.foundation/ScrollbarStyle.minimalHeight.<get-minimalHeight>|<get-minimalHeight>(){}[0]
final val shape // com.compose.sdl.scrollbar/ScrollbarStyle.shape|{}shape[0] final val shape // androidx.compose.foundation/ScrollbarStyle.shape|{}shape[0]
final fun <get-shape>(): androidx.compose.ui.graphics/Shape // com.compose.sdl.scrollbar/ScrollbarStyle.shape.<get-shape>|<get-shape>(){}[0] final fun <get-shape>(): androidx.compose.ui.graphics/Shape // androidx.compose.foundation/ScrollbarStyle.shape.<get-shape>|<get-shape>(){}[0]
final val thickness // com.compose.sdl.scrollbar/ScrollbarStyle.thickness|{}thickness[0] final val thickness // androidx.compose.foundation/ScrollbarStyle.thickness|{}thickness[0]
final fun <get-thickness>(): androidx.compose.ui.unit/Dp // com.compose.sdl.scrollbar/ScrollbarStyle.thickness.<get-thickness>|<get-thickness>(){}[0] final fun <get-thickness>(): androidx.compose.ui.unit/Dp // androidx.compose.foundation/ScrollbarStyle.thickness.<get-thickness>|<get-thickness>(){}[0]
final val unhoverColor // com.compose.sdl.scrollbar/ScrollbarStyle.unhoverColor|{}unhoverColor[0] final val unhoverColor // androidx.compose.foundation/ScrollbarStyle.unhoverColor|{}unhoverColor[0]
final fun <get-unhoverColor>(): androidx.compose.ui.graphics/Color // com.compose.sdl.scrollbar/ScrollbarStyle.unhoverColor.<get-unhoverColor>|<get-unhoverColor>(){}[0] final fun <get-unhoverColor>(): androidx.compose.ui.graphics/Color // androidx.compose.foundation/ScrollbarStyle.unhoverColor.<get-unhoverColor>|<get-unhoverColor>(){}[0]
final fun component1(): androidx.compose.ui.unit/Dp // androidx.compose.foundation/ScrollbarStyle.component1|component1(){}[0]
final fun component2(): androidx.compose.ui.unit/Dp // androidx.compose.foundation/ScrollbarStyle.component2|component2(){}[0]
final fun component3(): androidx.compose.ui.graphics/Shape // androidx.compose.foundation/ScrollbarStyle.component3|component3(){}[0]
final fun component4(): kotlin/Int // androidx.compose.foundation/ScrollbarStyle.component4|component4(){}[0]
final fun component5(): androidx.compose.ui.graphics/Color // androidx.compose.foundation/ScrollbarStyle.component5|component5(){}[0]
final fun component6(): androidx.compose.ui.graphics/Color // androidx.compose.foundation/ScrollbarStyle.component6|component6(){}[0]
final fun copy(androidx.compose.ui.unit/Dp = ..., androidx.compose.ui.unit/Dp = ..., androidx.compose.ui.graphics/Shape = ..., kotlin/Int = ..., androidx.compose.ui.graphics/Color = ..., androidx.compose.ui.graphics/Color = ...): androidx.compose.foundation/ScrollbarStyle // androidx.compose.foundation/ScrollbarStyle.copy|copy(androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.graphics.Shape;kotlin.Int;androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // androidx.compose.foundation/ScrollbarStyle.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // androidx.compose.foundation/ScrollbarStyle.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // androidx.compose.foundation/ScrollbarStyle.toString|toString(){}[0]
} }
final value class androidx.compose.foundation.lazy.grid/GridItemSpan { // androidx.compose.foundation.lazy.grid/GridItemSpan|null[0] final value class androidx.compose.foundation.lazy.grid/GridItemSpan { // androidx.compose.foundation.lazy.grid/GridItemSpan|null[0]
@@ -2197,10 +2216,15 @@ final val androidx.compose.foundation.text/androidx_compose_foundation_text_Keyb
final val androidx.compose.foundation.text/androidx_compose_foundation_text_KeyboardOptions$stableprop // androidx.compose.foundation.text/androidx_compose_foundation_text_KeyboardOptions$stableprop|#static{}androidx_compose_foundation_text_KeyboardOptions$stableprop[0] final val androidx.compose.foundation.text/androidx_compose_foundation_text_KeyboardOptions$stableprop // androidx.compose.foundation.text/androidx_compose_foundation_text_KeyboardOptions$stableprop|#static{}androidx_compose_foundation_text_KeyboardOptions$stableprop[0]
final val androidx.compose.foundation.text/androidx_compose_foundation_text_TextAutoSizeDefaults$stableprop // androidx.compose.foundation.text/androidx_compose_foundation_text_TextAutoSizeDefaults$stableprop|#static{}androidx_compose_foundation_text_TextAutoSizeDefaults$stableprop[0] final val androidx.compose.foundation.text/androidx_compose_foundation_text_TextAutoSizeDefaults$stableprop // androidx.compose.foundation.text/androidx_compose_foundation_text_TextAutoSizeDefaults$stableprop|#static{}androidx_compose_foundation_text_TextAutoSizeDefaults$stableprop[0]
final val androidx.compose.foundation.text/androidx_compose_foundation_text_TextFieldScrollState$stableprop // androidx.compose.foundation.text/androidx_compose_foundation_text_TextFieldScrollState$stableprop|#static{}androidx_compose_foundation_text_TextFieldScrollState$stableprop[0] final val androidx.compose.foundation.text/androidx_compose_foundation_text_TextFieldScrollState$stableprop // androidx.compose.foundation.text/androidx_compose_foundation_text_TextFieldScrollState$stableprop|#static{}androidx_compose_foundation_text_TextFieldScrollState$stableprop[0]
final val androidx.compose.foundation.v2/androidx_compose_foundation_v2_LazyLineContentAdapter_VisibleLine$stableprop // androidx.compose.foundation.v2/androidx_compose_foundation_v2_LazyLineContentAdapter_VisibleLine$stableprop|#static{}androidx_compose_foundation_v2_LazyLineContentAdapter_VisibleLine$stableprop[0]
final val androidx.compose.foundation.v2/maxScrollOffset // androidx.compose.foundation.v2/maxScrollOffset|@androidx.compose.foundation.v2.ScrollbarAdapter{}maxScrollOffset[0]
final fun (androidx.compose.foundation.v2/ScrollbarAdapter).<get-maxScrollOffset>(): kotlin/Double // androidx.compose.foundation.v2/maxScrollOffset.<get-maxScrollOffset>|<get-maxScrollOffset>@androidx.compose.foundation.v2.ScrollbarAdapter(){}[0]
final val androidx.compose.foundation/LocalIndication // androidx.compose.foundation/LocalIndication|{}LocalIndication[0] final val androidx.compose.foundation/LocalIndication // androidx.compose.foundation/LocalIndication|{}LocalIndication[0]
final fun <get-LocalIndication>(): androidx.compose.runtime/ProvidableCompositionLocal<androidx.compose.foundation/Indication> // androidx.compose.foundation/LocalIndication.<get-LocalIndication>|<get-LocalIndication>(){}[0] final fun <get-LocalIndication>(): androidx.compose.runtime/ProvidableCompositionLocal<androidx.compose.foundation/Indication> // androidx.compose.foundation/LocalIndication.<get-LocalIndication>|<get-LocalIndication>(){}[0]
final val androidx.compose.foundation/LocalOverscrollFactory // androidx.compose.foundation/LocalOverscrollFactory|{}LocalOverscrollFactory[0] final val androidx.compose.foundation/LocalOverscrollFactory // androidx.compose.foundation/LocalOverscrollFactory|{}LocalOverscrollFactory[0]
final fun <get-LocalOverscrollFactory>(): androidx.compose.runtime/ProvidableCompositionLocal<androidx.compose.foundation/OverscrollFactory?> // androidx.compose.foundation/LocalOverscrollFactory.<get-LocalOverscrollFactory>|<get-LocalOverscrollFactory>(){}[0] final fun <get-LocalOverscrollFactory>(): androidx.compose.runtime/ProvidableCompositionLocal<androidx.compose.foundation/OverscrollFactory?> // androidx.compose.foundation/LocalOverscrollFactory.<get-LocalOverscrollFactory>|<get-LocalOverscrollFactory>(){}[0]
final val androidx.compose.foundation/LocalScrollbarStyle // androidx.compose.foundation/LocalScrollbarStyle|{}LocalScrollbarStyle[0]
final fun <get-LocalScrollbarStyle>(): androidx.compose.runtime/ProvidableCompositionLocal<androidx.compose.foundation/ScrollbarStyle> // androidx.compose.foundation/LocalScrollbarStyle.<get-LocalScrollbarStyle>|<get-LocalScrollbarStyle>(){}[0]
final val androidx.compose.foundation/androidx_compose_foundation_BasicTooltipDefaults$stableprop // androidx.compose.foundation/androidx_compose_foundation_BasicTooltipDefaults$stableprop|#static{}androidx_compose_foundation_BasicTooltipDefaults$stableprop[0] final val androidx.compose.foundation/androidx_compose_foundation_BasicTooltipDefaults$stableprop // androidx.compose.foundation/androidx_compose_foundation_BasicTooltipDefaults$stableprop|#static{}androidx_compose_foundation_BasicTooltipDefaults$stableprop[0]
final val androidx.compose.foundation/androidx_compose_foundation_BorderStroke$stableprop // androidx.compose.foundation/androidx_compose_foundation_BorderStroke$stableprop|#static{}androidx_compose_foundation_BorderStroke$stableprop[0] final val androidx.compose.foundation/androidx_compose_foundation_BorderStroke$stableprop // androidx.compose.foundation/androidx_compose_foundation_BorderStroke$stableprop|#static{}androidx_compose_foundation_BorderStroke$stableprop[0]
final val androidx.compose.foundation/androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop // androidx.compose.foundation/androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop|#static{}androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop[0] final val androidx.compose.foundation/androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop // androidx.compose.foundation/androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop|#static{}androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop[0]
@@ -2208,10 +2232,8 @@ final val androidx.compose.foundation/androidx_compose_foundation_ComposeFoundat
final val androidx.compose.foundation/androidx_compose_foundation_MarqueeDefaults$stableprop // androidx.compose.foundation/androidx_compose_foundation_MarqueeDefaults$stableprop|#static{}androidx_compose_foundation_MarqueeDefaults$stableprop[0] final val androidx.compose.foundation/androidx_compose_foundation_MarqueeDefaults$stableprop // androidx.compose.foundation/androidx_compose_foundation_MarqueeDefaults$stableprop|#static{}androidx_compose_foundation_MarqueeDefaults$stableprop[0]
final val androidx.compose.foundation/androidx_compose_foundation_MutatorMutex$stableprop // androidx.compose.foundation/androidx_compose_foundation_MutatorMutex$stableprop|#static{}androidx_compose_foundation_MutatorMutex$stableprop[0] final val androidx.compose.foundation/androidx_compose_foundation_MutatorMutex$stableprop // androidx.compose.foundation/androidx_compose_foundation_MutatorMutex$stableprop|#static{}androidx_compose_foundation_MutatorMutex$stableprop[0]
final val androidx.compose.foundation/androidx_compose_foundation_ScrollState$stableprop // androidx.compose.foundation/androidx_compose_foundation_ScrollState$stableprop|#static{}androidx_compose_foundation_ScrollState$stableprop[0] final val androidx.compose.foundation/androidx_compose_foundation_ScrollState$stableprop // androidx.compose.foundation/androidx_compose_foundation_ScrollState$stableprop|#static{}androidx_compose_foundation_ScrollState$stableprop[0]
final val androidx.compose.foundation/androidx_compose_foundation_ScrollbarStyle$stableprop // androidx.compose.foundation/androidx_compose_foundation_ScrollbarStyle$stableprop|#static{}androidx_compose_foundation_ScrollbarStyle$stableprop[0]
final val com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop // com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop|#static{}com_compose_sdl_icons_IconDefaults$stableprop[0] final val com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop // com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop|#static{}com_compose_sdl_icons_IconDefaults$stableprop[0]
final val com.compose.sdl.scrollbar/LocalScrollbarStyle // com.compose.sdl.scrollbar/LocalScrollbarStyle|{}LocalScrollbarStyle[0]
final fun <get-LocalScrollbarStyle>(): androidx.compose.runtime/ProvidableCompositionLocal<com.compose.sdl.scrollbar/ScrollbarStyle> // com.compose.sdl.scrollbar/LocalScrollbarStyle.<get-LocalScrollbarStyle>|<get-LocalScrollbarStyle>(){}[0]
final val com.compose.sdl.scrollbar/com_compose_sdl_scrollbar_ScrollbarStyle$stableprop // com.compose.sdl.scrollbar/com_compose_sdl_scrollbar_ScrollbarStyle$stableprop|#static{}com_compose_sdl_scrollbar_ScrollbarStyle$stableprop[0]
final val com.compose.sdl.widgets/com_compose_sdl_widgets_SplitPaneDefaults$stableprop // com.compose.sdl.widgets/com_compose_sdl_widgets_SplitPaneDefaults$stableprop|#static{}com_compose_sdl_widgets_SplitPaneDefaults$stableprop[0] final val com.compose.sdl.widgets/com_compose_sdl_widgets_SplitPaneDefaults$stableprop // com.compose.sdl.widgets/com_compose_sdl_widgets_SplitPaneDefaults$stableprop|#static{}com_compose_sdl_widgets_SplitPaneDefaults$stableprop[0]
final fun (androidx.compose.foundation.content/TransferableContent).androidx.compose.foundation.content/hasMediaType(androidx.compose.foundation.content/MediaType): kotlin/Boolean // androidx.compose.foundation.content/hasMediaType|hasMediaType@androidx.compose.foundation.content.TransferableContent(androidx.compose.foundation.content.MediaType){}[0] final fun (androidx.compose.foundation.content/TransferableContent).androidx.compose.foundation.content/hasMediaType(androidx.compose.foundation.content/MediaType): kotlin/Boolean // androidx.compose.foundation.content/hasMediaType|hasMediaType@androidx.compose.foundation.content.TransferableContent(androidx.compose.foundation.content.MediaType){}[0]
@@ -2585,18 +2607,29 @@ final fun androidx.compose.foundation.text/androidx_compose_foundation_text_Text
final fun androidx.compose.foundation.text/rememberTextFieldHorizontalScrollState(kotlin/Int, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation.text/TextFieldScrollState // androidx.compose.foundation.text/rememberTextFieldHorizontalScrollState|rememberTextFieldHorizontalScrollState(kotlin.Int;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation.text/rememberTextFieldHorizontalScrollState(kotlin/Int, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation.text/TextFieldScrollState // androidx.compose.foundation.text/rememberTextFieldHorizontalScrollState|rememberTextFieldHorizontalScrollState(kotlin.Int;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation.text/rememberTextFieldScrollState(androidx.compose.foundation.gestures/Orientation, kotlin/Int, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation.text/TextFieldScrollState // androidx.compose.foundation.text/rememberTextFieldScrollState|rememberTextFieldScrollState(androidx.compose.foundation.gestures.Orientation;kotlin.Int;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation.text/rememberTextFieldScrollState(androidx.compose.foundation.gestures/Orientation, kotlin/Int, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation.text/TextFieldScrollState // androidx.compose.foundation.text/rememberTextFieldScrollState|rememberTextFieldScrollState(androidx.compose.foundation.gestures.Orientation;kotlin.Int;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation.text/rememberTextFieldVerticalScrollState(kotlin/Int, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation.text/TextFieldScrollState // androidx.compose.foundation.text/rememberTextFieldVerticalScrollState|rememberTextFieldVerticalScrollState(kotlin.Int;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation.text/rememberTextFieldVerticalScrollState(kotlin/Int, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation.text/TextFieldScrollState // androidx.compose.foundation.text/rememberTextFieldVerticalScrollState|rememberTextFieldVerticalScrollState(kotlin.Int;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation.v2/androidx_compose_foundation_v2_LazyLineContentAdapter_VisibleLine$stableprop_getter(): kotlin/Int // androidx.compose.foundation.v2/androidx_compose_foundation_v2_LazyLineContentAdapter_VisibleLine$stableprop_getter|androidx_compose_foundation_v2_LazyLineContentAdapter_VisibleLine$stableprop_getter(){}[0]
final fun androidx.compose.foundation/BasicTooltipBox(androidx.compose.ui.window/PopupPositionProvider, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.foundation/BasicTooltipState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/Boolean, kotlin/Boolean, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/BasicTooltipBox|BasicTooltipBox(androidx.compose.ui.window.PopupPositionProvider;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.foundation.BasicTooltipState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.Boolean;kotlin.Boolean;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation/BasicTooltipBox(androidx.compose.ui.window/PopupPositionProvider, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.foundation/BasicTooltipState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/Boolean, kotlin/Boolean, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/BasicTooltipBox|BasicTooltipBox(androidx.compose.ui.window.PopupPositionProvider;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.foundation.BasicTooltipState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.Boolean;kotlin.Boolean;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/BasicTooltipBox(androidx.compose.ui.window/PopupPositionProvider, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.foundation/BasicTooltipState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/Boolean, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/BasicTooltipBox|BasicTooltipBox(androidx.compose.ui.window.PopupPositionProvider;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.foundation.BasicTooltipState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.Boolean;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation/BasicTooltipBox(androidx.compose.ui.window/PopupPositionProvider, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.foundation/BasicTooltipState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/Boolean, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/BasicTooltipBox|BasicTooltipBox(androidx.compose.ui.window.PopupPositionProvider;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.foundation.BasicTooltipState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.Boolean;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/BasicTooltipState(kotlin/Boolean = ..., kotlin/Boolean = ..., androidx.compose.foundation/MutatorMutex = ...): androidx.compose.foundation/BasicTooltipState // androidx.compose.foundation/BasicTooltipState|BasicTooltipState(kotlin.Boolean;kotlin.Boolean;androidx.compose.foundation.MutatorMutex){}[0] final fun androidx.compose.foundation/BasicTooltipState(kotlin/Boolean = ..., kotlin/Boolean = ..., androidx.compose.foundation/MutatorMutex = ...): androidx.compose.foundation/BasicTooltipState // androidx.compose.foundation/BasicTooltipState|BasicTooltipState(kotlin.Boolean;kotlin.Boolean;androidx.compose.foundation.MutatorMutex){}[0]
final fun androidx.compose.foundation/BorderStroke(androidx.compose.ui.unit/Dp, androidx.compose.ui.graphics/Color): androidx.compose.foundation/BorderStroke // androidx.compose.foundation/BorderStroke|BorderStroke(androidx.compose.ui.unit.Dp;androidx.compose.ui.graphics.Color){}[0] final fun androidx.compose.foundation/BorderStroke(androidx.compose.ui.unit/Dp, androidx.compose.ui.graphics/Color): androidx.compose.foundation/BorderStroke // androidx.compose.foundation/BorderStroke|BorderStroke(androidx.compose.ui.unit.Dp;androidx.compose.ui.graphics.Color){}[0]
final fun androidx.compose.foundation/Canvas(androidx.compose.ui/Modifier, kotlin/Function1<androidx.compose.ui.graphics.drawscope/DrawScope, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int) // androidx.compose.foundation/Canvas|Canvas(androidx.compose.ui.Modifier;kotlin.Function1<androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun androidx.compose.foundation/Canvas(androidx.compose.ui/Modifier, kotlin/Function1<androidx.compose.ui.graphics.drawscope/DrawScope, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int) // androidx.compose.foundation/Canvas|Canvas(androidx.compose.ui.Modifier;kotlin.Function1<androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun androidx.compose.foundation/Canvas(androidx.compose.ui/Modifier, kotlin/String, kotlin/Function1<androidx.compose.ui.graphics.drawscope/DrawScope, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int) // androidx.compose.foundation/Canvas|Canvas(androidx.compose.ui.Modifier;kotlin.String;kotlin.Function1<androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun androidx.compose.foundation/Canvas(androidx.compose.ui/Modifier, kotlin/String, kotlin/Function1<androidx.compose.ui.graphics.drawscope/DrawScope, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int) // androidx.compose.foundation/Canvas|Canvas(androidx.compose.ui.Modifier;kotlin.String;kotlin.Function1<androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun androidx.compose.foundation/HorizontalScrollbar(androidx.compose.foundation.v2/ScrollbarAdapter, androidx.compose.ui/Modifier?, kotlin/Boolean, androidx.compose.foundation/ScrollbarStyle?, androidx.compose.foundation.interaction/MutableInteractionSource?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/HorizontalScrollbar|HorizontalScrollbar(androidx.compose.foundation.v2.ScrollbarAdapter;androidx.compose.ui.Modifier?;kotlin.Boolean;androidx.compose.foundation.ScrollbarStyle?;androidx.compose.foundation.interaction.MutableInteractionSource?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/HorizontalScrollbar(androidx.compose.foundation/ScrollbarAdapter, androidx.compose.ui/Modifier?, kotlin/Boolean, androidx.compose.foundation/ScrollbarStyle?, androidx.compose.foundation.interaction/MutableInteractionSource?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/HorizontalScrollbar|HorizontalScrollbar(androidx.compose.foundation.ScrollbarAdapter;androidx.compose.ui.Modifier?;kotlin.Boolean;androidx.compose.foundation.ScrollbarStyle?;androidx.compose.foundation.interaction.MutableInteractionSource?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/Image(androidx.compose.ui.graphics.painter/Painter, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/Image|Image(androidx.compose.ui.graphics.painter.Painter;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation/Image(androidx.compose.ui.graphics.painter/Painter, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/Image|Image(androidx.compose.ui.graphics.painter.Painter;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/Image(androidx.compose.ui.graphics.vector/ImageVector, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/Image|Image(androidx.compose.ui.graphics.vector.ImageVector;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation/Image(androidx.compose.ui.graphics.vector/ImageVector, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/Image|Image(androidx.compose.ui.graphics.vector.ImageVector;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/Image(androidx.compose.ui.graphics/ImageBitmap, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/Image|Image(androidx.compose.ui.graphics.ImageBitmap;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation/Image(androidx.compose.ui.graphics/ImageBitmap, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/Image|Image(androidx.compose.ui.graphics.ImageBitmap;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/Image(androidx.compose.ui.graphics/ImageBitmap, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/Image|Image(androidx.compose.ui.graphics.ImageBitmap;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation/Image(androidx.compose.ui.graphics/ImageBitmap, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/Image|Image(androidx.compose.ui.graphics.ImageBitmap;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/Image(androidx.compose.ui.graphics/ImageBitmap, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/Image|Image(androidx.compose.ui.graphics.ImageBitmap;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation/Image(androidx.compose.ui.graphics/ImageBitmap, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/Image|Image(androidx.compose.ui.graphics.ImageBitmap;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/MarqueeSpacing(androidx.compose.ui.unit/Dp): androidx.compose.foundation/MarqueeSpacing // androidx.compose.foundation/MarqueeSpacing|MarqueeSpacing(androidx.compose.ui.unit.Dp){}[0] final fun androidx.compose.foundation/MarqueeSpacing(androidx.compose.ui.unit/Dp): androidx.compose.foundation/MarqueeSpacing // androidx.compose.foundation/MarqueeSpacing|MarqueeSpacing(androidx.compose.ui.unit.Dp){}[0]
final fun androidx.compose.foundation/OldScrollbarAdapter(androidx.compose.foundation.lazy/LazyListState): androidx.compose.foundation/ScrollbarAdapter // androidx.compose.foundation/OldScrollbarAdapter|OldScrollbarAdapter(androidx.compose.foundation.lazy.LazyListState){}[0]
final fun androidx.compose.foundation/OldScrollbarAdapter(androidx.compose.foundation/ScrollState): androidx.compose.foundation/ScrollbarAdapter // androidx.compose.foundation/OldScrollbarAdapter|OldScrollbarAdapter(androidx.compose.foundation.ScrollState){}[0]
final fun androidx.compose.foundation/ScrollbarAdapter(androidx.compose.foundation.lazy.grid/LazyGridState): androidx.compose.foundation.v2/ScrollbarAdapter // androidx.compose.foundation/ScrollbarAdapter|ScrollbarAdapter(androidx.compose.foundation.lazy.grid.LazyGridState){}[0]
final fun androidx.compose.foundation/ScrollbarAdapter(androidx.compose.foundation.lazy/LazyListState): androidx.compose.foundation.v2/ScrollbarAdapter // androidx.compose.foundation/ScrollbarAdapter|ScrollbarAdapter(androidx.compose.foundation.lazy.LazyListState){}[0]
final fun androidx.compose.foundation/ScrollbarAdapter(androidx.compose.foundation.text/TextFieldScrollState): androidx.compose.foundation.v2/ScrollbarAdapter // androidx.compose.foundation/ScrollbarAdapter|ScrollbarAdapter(androidx.compose.foundation.text.TextFieldScrollState){}[0]
final fun androidx.compose.foundation/ScrollbarAdapter(androidx.compose.foundation/ScrollState): androidx.compose.foundation.v2/ScrollbarAdapter // androidx.compose.foundation/ScrollbarAdapter|ScrollbarAdapter(androidx.compose.foundation.ScrollState){}[0]
final fun androidx.compose.foundation/VerticalScrollbar(androidx.compose.foundation.v2/ScrollbarAdapter, androidx.compose.ui/Modifier?, kotlin/Boolean, androidx.compose.foundation/ScrollbarStyle?, androidx.compose.foundation.interaction/MutableInteractionSource?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/VerticalScrollbar|VerticalScrollbar(androidx.compose.foundation.v2.ScrollbarAdapter;androidx.compose.ui.Modifier?;kotlin.Boolean;androidx.compose.foundation.ScrollbarStyle?;androidx.compose.foundation.interaction.MutableInteractionSource?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/VerticalScrollbar(androidx.compose.foundation/ScrollbarAdapter, androidx.compose.ui/Modifier?, kotlin/Boolean, androidx.compose.foundation/ScrollbarStyle?, androidx.compose.foundation.interaction/MutableInteractionSource?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // androidx.compose.foundation/VerticalScrollbar|VerticalScrollbar(androidx.compose.foundation.ScrollbarAdapter;androidx.compose.ui.Modifier?;kotlin.Boolean;androidx.compose.foundation.ScrollbarStyle?;androidx.compose.foundation.interaction.MutableInteractionSource?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/androidx_compose_foundation_BasicTooltipDefaults$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_BasicTooltipDefaults$stableprop_getter|androidx_compose_foundation_BasicTooltipDefaults$stableprop_getter(){}[0] final fun androidx.compose.foundation/androidx_compose_foundation_BasicTooltipDefaults$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_BasicTooltipDefaults$stableprop_getter|androidx_compose_foundation_BasicTooltipDefaults$stableprop_getter(){}[0]
final fun androidx.compose.foundation/androidx_compose_foundation_BorderStroke$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_BorderStroke$stableprop_getter|androidx_compose_foundation_BorderStroke$stableprop_getter(){}[0] final fun androidx.compose.foundation/androidx_compose_foundation_BorderStroke$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_BorderStroke$stableprop_getter|androidx_compose_foundation_BorderStroke$stableprop_getter(){}[0]
final fun androidx.compose.foundation/androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop_getter|androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop_getter(){}[0] final fun androidx.compose.foundation/androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop_getter|androidx_compose_foundation_CombinedClickableNode_DoubleKeyClickState$stableprop_getter(){}[0]
@@ -2604,20 +2637,22 @@ final fun androidx.compose.foundation/androidx_compose_foundation_ComposeFoundat
final fun androidx.compose.foundation/androidx_compose_foundation_MarqueeDefaults$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_MarqueeDefaults$stableprop_getter|androidx_compose_foundation_MarqueeDefaults$stableprop_getter(){}[0] final fun androidx.compose.foundation/androidx_compose_foundation_MarqueeDefaults$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_MarqueeDefaults$stableprop_getter|androidx_compose_foundation_MarqueeDefaults$stableprop_getter(){}[0]
final fun androidx.compose.foundation/androidx_compose_foundation_MutatorMutex$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_MutatorMutex$stableprop_getter|androidx_compose_foundation_MutatorMutex$stableprop_getter(){}[0] final fun androidx.compose.foundation/androidx_compose_foundation_MutatorMutex$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_MutatorMutex$stableprop_getter|androidx_compose_foundation_MutatorMutex$stableprop_getter(){}[0]
final fun androidx.compose.foundation/androidx_compose_foundation_ScrollState$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_ScrollState$stableprop_getter|androidx_compose_foundation_ScrollState$stableprop_getter(){}[0] final fun androidx.compose.foundation/androidx_compose_foundation_ScrollState$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_ScrollState$stableprop_getter|androidx_compose_foundation_ScrollState$stableprop_getter(){}[0]
final fun androidx.compose.foundation/androidx_compose_foundation_ScrollbarStyle$stableprop_getter(): kotlin/Int // androidx.compose.foundation/androidx_compose_foundation_ScrollbarStyle$stableprop_getter|androidx_compose_foundation_ScrollbarStyle$stableprop_getter(){}[0]
final fun androidx.compose.foundation/checkScrollableContainerConstraints(androidx.compose.ui.unit/Constraints, androidx.compose.foundation.gestures/Orientation) // androidx.compose.foundation/checkScrollableContainerConstraints|checkScrollableContainerConstraints(androidx.compose.ui.unit.Constraints;androidx.compose.foundation.gestures.Orientation){}[0] final fun androidx.compose.foundation/checkScrollableContainerConstraints(androidx.compose.ui.unit/Constraints, androidx.compose.foundation.gestures/Orientation) // androidx.compose.foundation/checkScrollableContainerConstraints|checkScrollableContainerConstraints(androidx.compose.ui.unit.Constraints;androidx.compose.foundation.gestures.Orientation){}[0]
final fun androidx.compose.foundation/defaultScrollbarStyle(): androidx.compose.foundation/ScrollbarStyle // androidx.compose.foundation/defaultScrollbarStyle|defaultScrollbarStyle(){}[0]
final fun androidx.compose.foundation/isSystemInDarkTheme(androidx.compose.runtime/Composer?, kotlin/Int): kotlin/Boolean // androidx.compose.foundation/isSystemInDarkTheme|isSystemInDarkTheme(androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun androidx.compose.foundation/isSystemInDarkTheme(androidx.compose.runtime/Composer?, kotlin/Int): kotlin/Boolean // androidx.compose.foundation/isSystemInDarkTheme|isSystemInDarkTheme(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun androidx.compose.foundation/rememberBasicTooltipState(kotlin/Boolean, kotlin/Boolean, androidx.compose.foundation/MutatorMutex?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation/BasicTooltipState // androidx.compose.foundation/rememberBasicTooltipState|rememberBasicTooltipState(kotlin.Boolean;kotlin.Boolean;androidx.compose.foundation.MutatorMutex?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation/rememberBasicTooltipState(kotlin/Boolean, kotlin/Boolean, androidx.compose.foundation/MutatorMutex?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation/BasicTooltipState // androidx.compose.foundation/rememberBasicTooltipState|rememberBasicTooltipState(kotlin.Boolean;kotlin.Boolean;androidx.compose.foundation.MutatorMutex?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/rememberOldScrollbarAdapter(androidx.compose.foundation.lazy/LazyListState, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation/ScrollbarAdapter // androidx.compose.foundation/rememberOldScrollbarAdapter|rememberOldScrollbarAdapter(androidx.compose.foundation.lazy.LazyListState;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun androidx.compose.foundation/rememberOldScrollbarAdapter(androidx.compose.foundation/ScrollState, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation/ScrollbarAdapter // androidx.compose.foundation/rememberOldScrollbarAdapter|rememberOldScrollbarAdapter(androidx.compose.foundation.ScrollState;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun androidx.compose.foundation/rememberOverscrollEffect(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation/OverscrollEffect? // androidx.compose.foundation/rememberOverscrollEffect|rememberOverscrollEffect(androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun androidx.compose.foundation/rememberOverscrollEffect(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation/OverscrollEffect? // androidx.compose.foundation/rememberOverscrollEffect|rememberOverscrollEffect(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun androidx.compose.foundation/rememberScrollState(kotlin/Int, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation/ScrollState // androidx.compose.foundation/rememberScrollState|rememberScrollState(kotlin.Int;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun androidx.compose.foundation/rememberScrollState(kotlin/Int, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation/ScrollState // androidx.compose.foundation/rememberScrollState|rememberScrollState(kotlin.Int;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun androidx.compose.foundation/rememberScrollbarAdapter(androidx.compose.foundation.lazy.grid/LazyGridState, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation.v2/ScrollbarAdapter // androidx.compose.foundation/rememberScrollbarAdapter|rememberScrollbarAdapter(androidx.compose.foundation.lazy.grid.LazyGridState;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun androidx.compose.foundation/rememberScrollbarAdapter(androidx.compose.foundation.lazy/LazyListState, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation.v2/ScrollbarAdapter // androidx.compose.foundation/rememberScrollbarAdapter|rememberScrollbarAdapter(androidx.compose.foundation.lazy.LazyListState;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun androidx.compose.foundation/rememberScrollbarAdapter(androidx.compose.foundation.text/TextFieldScrollState, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation.v2/ScrollbarAdapter // androidx.compose.foundation/rememberScrollbarAdapter|rememberScrollbarAdapter(androidx.compose.foundation.text.TextFieldScrollState;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun androidx.compose.foundation/rememberScrollbarAdapter(androidx.compose.foundation/ScrollState, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation.v2/ScrollbarAdapter // androidx.compose.foundation/rememberScrollbarAdapter|rememberScrollbarAdapter(androidx.compose.foundation.ScrollState;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun com.compose.sdl.icons/IconFontIcon(kotlin/Int, kotlin/String, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics/Color, androidx.compose.ui.unit/Dp, kotlin.collections/List<androidx.compose.ui.text.font/FontVariation.Setting>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.icons/IconFontIcon|IconFontIcon(kotlin.Int;kotlin.String;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.Color;androidx.compose.ui.unit.Dp;kotlin.collections.List<androidx.compose.ui.text.font.FontVariation.Setting>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun com.compose.sdl.icons/IconFontIcon(kotlin/Int, kotlin/String, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics/Color, androidx.compose.ui.unit/Dp, kotlin.collections/List<androidx.compose.ui.text.font/FontVariation.Setting>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.icons/IconFontIcon|IconFontIcon(kotlin.Int;kotlin.String;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.Color;androidx.compose.ui.unit.Dp;kotlin.collections.List<androidx.compose.ui.text.font.FontVariation.Setting>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop_getter(): kotlin/Int // com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop_getter|com_compose_sdl_icons_IconDefaults$stableprop_getter(){}[0] final fun com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop_getter(): kotlin/Int // com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop_getter|com_compose_sdl_icons_IconDefaults$stableprop_getter(){}[0]
final fun com.compose.sdl.modifier/rememberMutableInteractionSource(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation.interaction/MutableInteractionSource // com.compose.sdl.modifier/rememberMutableInteractionSource|rememberMutableInteractionSource(androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun com.compose.sdl.modifier/rememberMutableInteractionSource(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation.interaction/MutableInteractionSource // com.compose.sdl.modifier/rememberMutableInteractionSource|rememberMutableInteractionSource(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun com.compose.sdl.scrollbar/HorizontalScrollbar(com.compose.sdl.scrollbar/ScrollbarAdapter, androidx.compose.ui/Modifier?, kotlin/Boolean, com.compose.sdl.scrollbar/ScrollbarStyle?, androidx.compose.foundation.interaction/MutableInteractionSource?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.scrollbar/HorizontalScrollbar|HorizontalScrollbar(com.compose.sdl.scrollbar.ScrollbarAdapter;androidx.compose.ui.Modifier?;kotlin.Boolean;com.compose.sdl.scrollbar.ScrollbarStyle?;androidx.compose.foundation.interaction.MutableInteractionSource?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun com.compose.sdl.scrollbar/VerticalScrollbar(com.compose.sdl.scrollbar/ScrollbarAdapter, androidx.compose.ui/Modifier?, kotlin/Boolean, com.compose.sdl.scrollbar/ScrollbarStyle?, androidx.compose.foundation.interaction/MutableInteractionSource?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.scrollbar/VerticalScrollbar|VerticalScrollbar(com.compose.sdl.scrollbar.ScrollbarAdapter;androidx.compose.ui.Modifier?;kotlin.Boolean;com.compose.sdl.scrollbar.ScrollbarStyle?;androidx.compose.foundation.interaction.MutableInteractionSource?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun com.compose.sdl.scrollbar/com_compose_sdl_scrollbar_ScrollbarStyle$stableprop_getter(): kotlin/Int // com.compose.sdl.scrollbar/com_compose_sdl_scrollbar_ScrollbarStyle$stableprop_getter|com_compose_sdl_scrollbar_ScrollbarStyle$stableprop_getter(){}[0]
final fun com.compose.sdl.scrollbar/defaultScrollbarStyle(): com.compose.sdl.scrollbar/ScrollbarStyle // com.compose.sdl.scrollbar/defaultScrollbarStyle|defaultScrollbarStyle(){}[0]
final fun com.compose.sdl.scrollbar/rememberScrollbarAdapter(androidx.compose.foundation.lazy/LazyListState, androidx.compose.runtime/Composer?, kotlin/Int): com.compose.sdl.scrollbar/ScrollbarAdapter // com.compose.sdl.scrollbar/rememberScrollbarAdapter|rememberScrollbarAdapter(androidx.compose.foundation.lazy.LazyListState;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun com.compose.sdl.scrollbar/rememberScrollbarAdapter(androidx.compose.foundation/ScrollState, androidx.compose.runtime/Composer?, kotlin/Int): com.compose.sdl.scrollbar/ScrollbarAdapter // com.compose.sdl.scrollbar/rememberScrollbarAdapter|rememberScrollbarAdapter(androidx.compose.foundation.ScrollState;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun com.compose.sdl.text/IconText(kotlin/String, kotlin/String, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics/Color, androidx.compose.ui.unit/TextUnit, androidx.compose.ui.text.style/TextAlign, kotlin.collections/List<androidx.compose.ui.text.font/FontVariation.Setting>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.text/IconText|IconText(kotlin.String;kotlin.String;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.Color;androidx.compose.ui.unit.TextUnit;androidx.compose.ui.text.style.TextAlign;kotlin.collections.List<androidx.compose.ui.text.font.FontVariation.Setting>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun com.compose.sdl.text/IconText(kotlin/String, kotlin/String, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics/Color, androidx.compose.ui.unit/TextUnit, androidx.compose.ui.text.style/TextAlign, kotlin.collections/List<androidx.compose.ui.text.font/FontVariation.Setting>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.text/IconText|IconText(kotlin.String;kotlin.String;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.Color;androidx.compose.ui.unit.TextUnit;androidx.compose.ui.text.style.TextAlign;kotlin.collections.List<androidx.compose.ui.text.font.FontVariation.Setting>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun com.compose.sdl.text/IconText(kotlin/String, kotlin/String, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics/Color, androidx.compose.ui.unit/TextUnit, androidx.compose.ui.text.style/TextAlign?, kotlin.collections/List<androidx.compose.ui.text.font/FontVariation.Setting>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.text/IconText|IconText(kotlin.String;kotlin.String;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.Color;androidx.compose.ui.unit.TextUnit;androidx.compose.ui.text.style.TextAlign?;kotlin.collections.List<androidx.compose.ui.text.font.FontVariation.Setting>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun com.compose.sdl.text/IconText(kotlin/String, kotlin/String, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics/Color, androidx.compose.ui.unit/TextUnit, androidx.compose.ui.text.style/TextAlign?, kotlin.collections/List<androidx.compose.ui.text.font/FontVariation.Setting>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.text/IconText|IconText(kotlin.String;kotlin.String;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.Color;androidx.compose.ui.unit.TextUnit;androidx.compose.ui.text.style.TextAlign?;kotlin.collections.List<androidx.compose.ui.text.font.FontVariation.Setting>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun com.compose.sdl.widgets/HorizontalSplitPane(androidx.compose.ui/Modifier?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.widgets/HorizontalSplitPane|HorizontalSplitPane(androidx.compose.ui.Modifier?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun com.compose.sdl.widgets/HorizontalSplitPane(androidx.compose.ui/Modifier?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.widgets/HorizontalSplitPane|HorizontalSplitPane(androidx.compose.ui.Modifier?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
@@ -48,10 +48,10 @@ kotlin {
commonMain { commonMain {
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
dependencies { dependencies {
api(project(":ui")) api(project(":compose:ui:ui"))
api(project(":animation-core")) api(project(":compose:animation:animation-core"))
api(project(":animation")) api(project(":compose:animation:animation"))
api(project(":foundation-layout")) api(project(":compose:foundation:foundation-layout"))
} }
} }
nativeMain { nativeMain {
@@ -356,7 +356,6 @@ commonMain/kotlin/ -> src/vendor/common/kotlin/
# | commonMain/kotlin/androidx/compose/foundation/text/selection/TextPreparedSelection.kt -> src/vendor/common/kotlin/androidx/compose/foundation/text/selection/TextPreparedSelection.kt # | commonMain/kotlin/androidx/compose/foundation/text/selection/TextPreparedSelection.kt -> src/vendor/common/kotlin/androidx/compose/foundation/text/selection/TextPreparedSelection.kt
# | commonMain/kotlin/androidx/compose/foundation/text/selection/TextSelectionColors.kt -> src/vendor/common/kotlin/androidx/compose/foundation/text/selection/TextSelectionColors.kt # | commonMain/kotlin/androidx/compose/foundation/text/selection/TextSelectionColors.kt -> src/vendor/common/kotlin/androidx/compose/foundation/text/selection/TextSelectionColors.kt
# | commonMain/kotlin/androidx/compose/foundation/text/selection/TextSelectionDelegate.kt -> src/vendor/common/kotlin/androidx/compose/foundation/text/selection/TextSelectionDelegate.kt # | commonMain/kotlin/androidx/compose/foundation/text/selection/TextSelectionDelegate.kt -> src/vendor/common/kotlin/androidx/compose/foundation/text/selection/TextSelectionDelegate.kt
!commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionLayout.kt
macosMain/kotlin/androidx/compose/foundation/text/selection/DefaultTextSelectionColors.macos.kt -> src/vendor/native/kotlin/androidx/compose/foundation/text/selection/DefaultTextSelectionColors.native.kt macosMain/kotlin/androidx/compose/foundation/text/selection/DefaultTextSelectionColors.macos.kt -> src/vendor/native/kotlin/androidx/compose/foundation/text/selection/DefaultTextSelectionColors.native.kt
@@ -1,810 +0,0 @@
@file:Suppress("OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE", "LESS_VISIBLE_TYPE_ACCESS_IN_INLINE")
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// MANUAL VENDOR of upstream compose/foundation/foundation/src/commonMain/kotlin/
// androidx/compose/foundation/text/selection/SelectionLayout.kt.
// VENDOR-BASE: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionLayout.kt @ v1.12.0-beta03+dev4483
//
// Change vs upstream: MultiSelectionLayout.crossStatus and slotToIndex clamp their
// infoList index to the valid range. Upstream assumes that if the drag position never
// resolves ON or BEFORE any selectable, at least one slot is anchored on a text (odd).
// That assumption breaks when a mouse-down starts a NEW selection AFTER every selectable
// in the container - both slots stay UNASSIGNED and get defaulted to lastSlot = 2N by
// SelectionLayoutBuilder.build(), so startSlot / 2 == infoList.size (OOB). Repro:
// apidemo response viewer, drag-select in the empty area below the last body block.
package androidx.compose.foundation.text.selection
import androidx.collection.LongIntMap
import androidx.collection.LongObjectMap
import androidx.collection.MutableLongIntMap
import androidx.collection.buildLongObjectMap
import androidx.collection.emptyLongObjectMap
import androidx.collection.longObjectMapOf
import androidx.collection.mutableLongIntMapOf
import androidx.collection.mutableLongObjectMapOf
import androidx.compose.foundation.internal.checkPrecondition
import androidx.compose.foundation.text.selection.Direction.AFTER
import androidx.compose.foundation.text.selection.Direction.BEFORE
import androidx.compose.foundation.text.selection.Direction.ON
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastForEachIndexed
/**
* Selection data around how the pointer relates to the actual positions of the Text components.
*
* # Explanation of Slots
*
* The Slot value is meant to sit either *on* an index or *between* indices. The former means the
* pointer is on a `Text` (like slot value `1` and index `0` below). The latter means the pointer is
* not on a `Text`, but between `Text`s (like slot value `0` or `2` below). So a slot value of `2`
* means that the pointer is between the `Text`s at index `0` and `1`, perhaps in padding or a
* non-selectable `Text`.
*
* ```
* slot value 0 1 2 3 4 5 6 7 8 9 10
* info index 0 1 2 3 4
* ```
*
* ## Mappings:
* The `X` represents an impossible slot assignment The `|`, `/`, and `\` represent a slot mapping.
*
* ### Mapping minimum slot:
* ```
* slot value 0 1 2 3 4 5 6 7 8 9 10
* \ | \ | \ | \ | \ | X
* info index 0 1 2 3 4
*
* min-slot index = slot / 2
* ```
*
* Minimum slot cannot be after the final `Text` (index `4`).
*
* ### Mapping maximum slot:
* ```
* slot value 0 1 2 3 4 5 6 7 8 9 10
* X | / | / | / | / | /
* info index 0 1 2 3 4
* max-slot index = (slot - 1) / 2
* ```
*
* Maximum slot cannot be before the first `Text` (index `0`).
*
* ## Assertions
* * The non-dragging slot should always be directly on a text (odd) because the non-dragging handle
* must be anchored somewhere.
* * Because of this, we can determine that if `startSlot == endSlot` then it also follows that
* `startSlot` and `endSlot` are even.
*/
internal interface SelectionLayout {
/** The number of [SelectableInfo]s in this [SelectionLayout]. */
val size: Int
/** The slot of the start anchor. */
val startSlot: Int
/** The slot of the end anchor. */
val endSlot: Int
/** The [CrossStatus] of this layout as determined by the slot/offsets. */
val crossStatus: CrossStatus
/** The [SelectableInfo] that the start is on. */
val startInfo: SelectableInfo
/** The [SelectableInfo] that the end is on. */
val endInfo: SelectableInfo
/** The [SelectableInfo] that the start/end is on as determined by [isStartHandle]. */
val currentInfo: SelectableInfo
/** The [SelectableInfo] for the first selectable on the screen. */
val firstInfo: SelectableInfo
/** The [SelectableInfo] for the last selectable on the screen. */
val lastInfo: SelectableInfo
/**
* Run a function on every [SelectableInfo] between [firstInfo] and [lastInfo] (not including
* [firstInfo]/[lastInfo]).
*/
fun forEachMiddleInfo(block: (SelectableInfo) -> Unit)
/** Whether the start or end anchor is currently being moved. */
val isStartHandle: Boolean
/** The previous [Selection] that we are modifying. */
val previousSelection: Selection?
/** Returns the [SelectableInfo] of the selectable with the given id. */
fun infoForSelectable(selectableId: Long): SelectableInfo?
/**
* Whether this layout, compared to another layout, has any relevant changes that would require
* recomputing selection.
*
* @param other the selection layout to check for changes compared to this one
*/
fun shouldRecomputeSelection(other: SelectionLayout?): Boolean
/**
* Splits a selection into a Map of selectable ID to Selections limited to that selectable ID.
*
* @param selection The selection to turn into subSelections
*/
fun createSubSelections(selection: Selection): LongObjectMap<Selection>
}
private class MultiSelectionLayout(
val selectableIdToInfoListIndex: LongIntMap,
val infoList: List<SelectableInfo>,
override val startSlot: Int,
override val endSlot: Int,
override val isStartHandle: Boolean,
override val previousSelection: Selection?,
) : SelectionLayout {
init {
checkPrecondition(infoList.size > 1) {
"MultiSelectionLayout requires an infoList size greater than 1, was ${infoList.size}."
}
}
private var _infoBySelectableId: LongObjectMap<SelectableInfo>? = null
private val infoBySelectableId: LongObjectMap<SelectableInfo>
get() {
var result = _infoBySelectableId
if (result == null) {
result = buildLongObjectMap { infoList.fastForEach { put(it.selectableId, it) } }
_infoBySelectableId = result
}
return result
}
// Most of these properties are unused unless shouldRecomputeSelection returns true,
// hence why getters are used everywhere.
override val size
get() = infoList.size
override val crossStatus: CrossStatus
get() =
when {
startSlot < endSlot -> CrossStatus.NOT_CROSSED
startSlot > endSlot -> CrossStatus.CROSSED
// FORK CHANGE: clamp when the gesture starts past every selectable, both slots
// default to lastSlot = 2 * infoList.size, so slot / 2 would be out of bounds.
else -> infoList[(startSlot / 2).coerceAtMost(infoList.lastIndex)].rawCrossStatus
}
override val startInfo: SelectableInfo
get() = infoList[startOrEndSlotToIndex(startSlot, isStartSlot = true)]
override val endInfo: SelectableInfo
get() = infoList[startOrEndSlotToIndex(endSlot, isStartSlot = false)]
override val currentInfo: SelectableInfo
get() = if (isStartHandle) startInfo else endInfo
override val firstInfo: SelectableInfo
get() = if (crossStatus == CrossStatus.CROSSED) endInfo else startInfo
override val lastInfo: SelectableInfo
get() = if (crossStatus == CrossStatus.CROSSED) startInfo else endInfo
override fun forEachMiddleInfo(block: (SelectableInfo) -> Unit) {
val minIndex = getInfoListIndexBySelectableId(firstInfo.selectableId)
val maxIndex = getInfoListIndexBySelectableId(lastInfo.selectableId)
if (minIndex + 1 >= maxIndex) {
return
}
for (i in minIndex + 1 until maxIndex) {
block(infoList[i])
}
}
override fun infoForSelectable(selectableId: Long): SelectableInfo? {
return infoBySelectableId[selectableId]
}
override fun shouldRecomputeSelection(other: SelectionLayout?): Boolean =
previousSelection == null ||
other == null ||
other !is MultiSelectionLayout ||
isStartHandle != other.isStartHandle ||
startSlot != other.startSlot ||
endSlot != other.endSlot ||
shouldAnyInfoRecomputeSelection(other)
private fun shouldAnyInfoRecomputeSelection(other: MultiSelectionLayout): Boolean {
if (size != other.size) return true
for (i in infoList.indices) {
val thisInfo = infoList[i]
val otherInfo = other.infoList[i]
if (thisInfo.shouldRecomputeSelection(otherInfo)) {
return true
}
}
return false
}
override fun createSubSelections(selection: Selection): LongObjectMap<Selection> =
createSubSelections(
selection = selection,
sortedItems = infoList,
getId = { it.selectableId },
getSelectAll = { info, _ ->
if (selection.handlesCrossed) {
info.makeSingleLayoutSelection(info.textLength, 0)
} else {
info.makeSingleLayoutSelection(0, info.textLength)
}
},
createBoundarySelection = { info, isStart, offset, _ ->
val isCrossed = selection.handlesCrossed
if (isStart) {
if (isCrossed) {
info.makeSingleLayoutSelection(start = offset, end = 0)
} else {
info.makeSingleLayoutSelection(start = offset, end = info.textLength)
}
} else {
if (isCrossed) {
info.makeSingleLayoutSelection(start = info.textLength, end = offset)
} else {
info.makeSingleLayoutSelection(start = 0, end = offset)
}
}
},
)
override fun toString(): String =
"MultiSelectionLayout(isStartHandle=$isStartHandle, " +
"startPosition=${(startSlot + 1).toFloat() / 2}, " +
"endPosition=${(endSlot + 1).toFloat() / 2}, " +
"crossed=$crossStatus, " +
"infos=${
buildString {
append("[\n\t")
var first = true
infoList
.fastForEachIndexed { index, info ->
if (first) {
first = false
} else {
append(",\n\t")
}
append("${(index + 1)} -> $info")
}
append("\n]")
}
})"
private fun startOrEndSlotToIndex(slot: Int, isStartSlot: Boolean): Int =
slotToIndex(
slot = slot,
isMinimumSlot =
when (crossStatus) {
// collapsed: doesn't matter whether true or false, it will result in the same
// index
CrossStatus.COLLAPSED -> true
CrossStatus.NOT_CROSSED -> isStartSlot
CrossStatus.CROSSED -> !isStartSlot
},
)
private fun slotToIndex(slot: Int, isMinimumSlot: Boolean): Int {
val slotAdjustment = if (isMinimumSlot) 0 else 1
// FORK CHANGE: clamp when the gesture starts past every selectable, slots default
// to lastSlot = 2 * infoList.size, so slot / 2 would be out of bounds.
return ((slot - slotAdjustment) / 2).coerceIn(0, infoList.lastIndex)
}
private fun getInfoListIndexBySelectableId(id: Long): Int =
try {
selectableIdToInfoListIndex[id]
} catch (e: NoSuchElementException) {
throw IllegalStateException("Invalid selectableId: $id", e)
}
}
/**
* Create a selection layout that has only one slot.
*
* @param isStartHandle whether this is the start or end anchor
* @param previousSelection the previous selection
* @param info the single [SelectableInfo]
*/
private class SingleSelectionLayout(
override val isStartHandle: Boolean,
override val startSlot: Int,
override val endSlot: Int,
override val previousSelection: Selection?,
private val info: SelectableInfo,
) : SelectionLayout {
companion object {
const val DEFAULT_SLOT = 1
const val DEFAULT_SELECTABLE_ID = 1L
}
override val size
get() = 1
override val crossStatus: CrossStatus
get() =
when {
startSlot < endSlot -> CrossStatus.NOT_CROSSED
startSlot > endSlot -> CrossStatus.CROSSED
else -> info.rawCrossStatus
}
override val startInfo: SelectableInfo
get() = info
override val endInfo: SelectableInfo
get() = info
override val currentInfo: SelectableInfo
get() = info
override val firstInfo: SelectableInfo
get() = info
override val lastInfo: SelectableInfo
get() = info
override fun forEachMiddleInfo(block: (SelectableInfo) -> Unit) {
// there are no middle infos, so do nothing
}
override fun infoForSelectable(selectableId: Long): SelectableInfo? {
return if (selectableId == info.selectableId) info else null
}
override fun shouldRecomputeSelection(other: SelectionLayout?): Boolean =
previousSelection == null ||
other == null ||
other !is SingleSelectionLayout ||
startSlot != other.startSlot ||
endSlot != other.endSlot ||
isStartHandle != other.isStartHandle ||
info.shouldRecomputeSelection(other.info)
override fun createSubSelections(selection: Selection): LongObjectMap<Selection> {
val finalSelection =
selection.run {
// uncross handles if necessary
if (
(!handlesCrossed && start.offset > end.offset) ||
(handlesCrossed && start.offset <= end.offset)
) {
copy(handlesCrossed = !handlesCrossed)
} else {
this
}
}
return longObjectMapOf(info.selectableId, finalSelection)
}
override fun toString(): String =
"SingleSelectionLayout(isStartHandle=$isStartHandle, crossed=$crossStatus, info=\n\t$info)"
}
/**
* Create a selection layout that has only one slot.
*
* This is intended for TextField, where multiple selectables is of no concern.
*
* @param layoutResult the [TextLayoutResult] for the text field
* @param rawStartHandleOffset the index of the start handle
* @param rawEndHandleOffset the index of the end handle
* @param rawPreviousHandleOffset the previous handle offset based on [isStartHandle], or
* [UNASSIGNED_SLOT] if none
* @param previousSelectionRange the previous selection
* @param isStartOfSelection whether this is the start of a selection gesture (no previous context)
* @param isStartHandle whether this is the start or end anchor
*/
internal fun getTextFieldSelectionLayout(
layoutResult: TextLayoutResult,
rawStartHandleOffset: Int,
rawEndHandleOffset: Int,
rawPreviousHandleOffset: Int,
previousSelectionRange: TextRange,
isStartOfSelection: Boolean,
isStartHandle: Boolean,
): SelectionLayout =
SingleSelectionLayout(
isStartHandle = isStartHandle,
startSlot = SingleSelectionLayout.DEFAULT_SLOT,
endSlot = SingleSelectionLayout.DEFAULT_SLOT,
previousSelection =
if (isStartOfSelection) null
else
Selection(
start =
Selection.AnchorInfo(
layoutResult.getTextDirectionForOffset(previousSelectionRange.start),
previousSelectionRange.start,
SingleSelectionLayout.DEFAULT_SELECTABLE_ID,
),
end =
Selection.AnchorInfo(
layoutResult.getTextDirectionForOffset(previousSelectionRange.end),
previousSelectionRange.end,
SingleSelectionLayout.DEFAULT_SELECTABLE_ID,
),
handlesCrossed = previousSelectionRange.reversed,
),
info =
SelectableInfo(
selectableId = SingleSelectionLayout.DEFAULT_SELECTABLE_ID,
slot = SingleSelectionLayout.DEFAULT_SLOT,
rawStartHandleOffset = rawStartHandleOffset,
rawEndHandleOffset = rawEndHandleOffset,
textLayoutResult = layoutResult,
rawPreviousHandleOffset = rawPreviousHandleOffset,
),
)
/** Whether something is crossed as determined by the position of the start/end. */
internal enum class CrossStatus {
/** The start comes after the end. */
CROSSED,
/** The start comes before the end. */
NOT_CROSSED,
/** The start is the same as the end. */
COLLAPSED,
}
/** Slot has not been assigned yet */
internal const val UNASSIGNED_SLOT = -1
/**
* A builder for [SelectionLayout] that ensures the data structures and slots are properly
* constructed.
*
* @param previousHandlePosition the previous handle position matching the handle directed to by
* [isStartHandle]
* @param containerCoordinates the coordinates of the [SelectionContainer] for converting
* [SelectionContainer] coordinates to their respective [Selectable] coordinates
* @param isStartHandle whether the currently pressed/clicked handle is the start
* @param previousLayout The [SelectionLayout] created when [currentPosition] was
* [previousHandlePosition]. When non-null, it is used to obtain
* [SelectableInfo.rawPreviousHandleOffset] instead of re-computing it from
* [previousHandlePosition]. Note that this is not just an optimization. When selectables are
* moved (due to drag-to-scroll, for example) inside the selection container, it becomes
* impossible to correctly deduce [SelectableInfo.rawPreviousHandleOffset] from
* [previousHandlePosition] (because to do that, the "previous" layout coordinates are needed, but
* are not available).
* @param selectableIdOrderingComparator determines the ordering of selectables by their IDs
* @param allowSelectionBetweenSelectables whether selection in the "empty" area where there are no
* selectables is allowed.
*/
internal class SelectionLayoutBuilder(
val currentPosition: Offset,
val previousHandlePosition: Offset,
val containerCoordinates: LayoutCoordinates,
val isStartHandle: Boolean,
val previousSelection: Selection?,
val previousLayout: SelectionLayout?,
val selectableIdOrderingComparator: Comparator<Long>,
val allowSelectionBetweenSelectables: Boolean = false,
) {
private val selectableIdToInfoListIndex: MutableLongIntMap = mutableLongIntMapOf()
private val infoList: MutableList<SelectableInfo> = mutableListOf()
private var startSlot: Int = UNASSIGNED_SLOT
private var endSlot: Int = UNASSIGNED_SLOT
private var currentSlot: Int = UNASSIGNED_SLOT
/**
* Finishes building the [SelectionLayout] and returns it.
*
* @return the [SelectionLayout] or null if no [SelectableInfo]s were added.
*/
fun build(): SelectionLayout? {
val lastSlot = currentSlot + 1
return when (infoList.size) {
0 -> {
null
}
1 -> {
SingleSelectionLayout(
info = infoList.single(),
startSlot = if (startSlot == UNASSIGNED_SLOT) lastSlot else startSlot,
endSlot = if (endSlot == UNASSIGNED_SLOT) lastSlot else endSlot,
previousSelection = previousSelection,
isStartHandle = isStartHandle,
)
}
else -> {
MultiSelectionLayout(
selectableIdToInfoListIndex = selectableIdToInfoListIndex,
infoList = infoList,
startSlot = if (startSlot == UNASSIGNED_SLOT) lastSlot else startSlot,
endSlot = if (endSlot == UNASSIGNED_SLOT) lastSlot else endSlot,
isStartHandle = isStartHandle,
previousSelection = previousSelection,
)
}
}
}
/** Appends a selection info to this builder. */
fun appendInfo(
selectableId: Long,
rawStartHandleOffset: Int,
startXHandleDirection: Direction,
startYHandleDirection: Direction,
rawEndHandleOffset: Int,
endXHandleDirection: Direction,
endYHandleDirection: Direction,
rawPreviousHandleOffset: Int,
textLayoutResult: TextLayoutResult,
): SelectableInfo {
// We need currentSlot to equal the slot of the "last" info when getLayout is called,
// so increment this before adding the info and leave the correct slot in place at the end.
currentSlot += 2
val selectableInfo =
SelectableInfo(
selectableId = selectableId,
slot = currentSlot,
rawStartHandleOffset = rawStartHandleOffset,
rawEndHandleOffset = rawEndHandleOffset,
rawPreviousHandleOffset = rawPreviousHandleOffset,
textLayoutResult = textLayoutResult,
)
startSlot = updateSlot(startSlot, startXHandleDirection, startYHandleDirection)
endSlot = updateSlot(endSlot, endXHandleDirection, endYHandleDirection)
selectableIdToInfoListIndex[selectableId] = infoList.size
infoList += selectableInfo
return selectableInfo
}
/**
* Find the slot for a selectable given the current position's directions from the selectable.
*
* The selectables must be ordered in the order in which they would be selected, and then this
* function should be called for each of those selectables.
*
* It is expected that the input [slot] is also assigned the result of this function.
*
* This function is stateful.
*
* @param slot the current value of this slot.
* @param xPositionDirection Where the x-position is relative to the selectable
* @param yPositionDirection Where the y-position is relative to the selectable
*/
private fun updateSlot(
slot: Int,
xPositionDirection: Direction,
yPositionDirection: Direction,
): Int {
if (slot != UNASSIGNED_SLOT) {
// don't overwrite if the slot has already been determined
return slot
}
// slot has not been determined yet,
// see if we are on or past the selectable we are looking for
return when (resolve2dDirection(xPositionDirection, yPositionDirection)) {
// If we get here, that means we never found a selectable that contains our gesture
// position. This is the first selectable that is after the position,
// so our slot must be between the previous and current selectables.
BEFORE -> currentSlot - 1
// The gesture position is directly on this selectable, so use this one.
ON -> currentSlot
// keep looking
AFTER -> slot
}
}
}
/** Where the position of a cursor/press is compared to a selectable. */
internal enum class Direction {
/** The cursor/press is before the selectable */
BEFORE,
/** The cursor/press is on the selectable */
ON,
/** The cursor/press is after the selectable */
AFTER,
}
/**
* Determine direction based on an x/y direction.
*
* This will use the [y] direction unless it is [ON], in which case it will use the [x] direction.
*/
internal fun resolve2dDirection(x: Direction, y: Direction): Direction =
when (y) {
BEFORE -> BEFORE
ON ->
when (x) {
BEFORE -> BEFORE
ON -> ON
AFTER -> AFTER
}
AFTER -> AFTER
}
/** Data about a specific selectable within a [SelectionLayout]. */
internal class SelectableInfo(
val selectableId: Long,
val slot: Int,
val rawStartHandleOffset: Int,
val rawEndHandleOffset: Int,
val rawPreviousHandleOffset: Int,
val textLayoutResult: TextLayoutResult,
) {
/** The [String] in the selectable. */
val inputText: String
get() = textLayoutResult.layoutInput.text.text
/** The length of the [String] in the selectable. */
val textLength: Int
get() = inputText.length
/** Whether the raw offsets of this info are crossed. */
val rawCrossStatus: CrossStatus
get() =
when {
rawStartHandleOffset < rawEndHandleOffset -> CrossStatus.NOT_CROSSED
rawStartHandleOffset > rawEndHandleOffset -> CrossStatus.CROSSED
else -> CrossStatus.COLLAPSED
}
private val startRunDirection
get() = textLayoutResult.getTextDirectionForOffset(rawStartHandleOffset)
private val endRunDirection
get() = textLayoutResult.getTextDirectionForOffset(rawEndHandleOffset)
/**
* Whether this info, compared to another info, has any relevant changes that would require
* recomputing selection.
*
* @param other the selectable info to check for changes compared to this one
*/
fun shouldRecomputeSelection(other: SelectableInfo): Boolean =
selectableId != other.selectableId ||
rawStartHandleOffset != other.rawStartHandleOffset ||
rawEndHandleOffset != other.rawEndHandleOffset
/** Get a [Selection.AnchorInfo] for this [SelectableInfo] at the given [offset]. */
fun anchorForOffset(offset: Int): Selection.AnchorInfo =
Selection.AnchorInfo(
direction = textLayoutResult.getTextDirectionForOffset(offset),
offset = offset,
selectableId = selectableId,
)
/**
* Get a [Selection] within the selectable represented by this [SelectableInfo] for the given
* [start] and [end] offsets.
*/
fun makeSingleLayoutSelection(start: Int, end: Int): Selection =
Selection(
start = anchorForOffset(start),
end = anchorForOffset(end),
handlesCrossed = start > end,
)
override fun toString(): String =
"SelectionInfo(id=$selectableId, " +
"range=($rawStartHandleOffset-$startRunDirection,$rawEndHandleOffset-$endRunDirection), " +
"prevOffset=$rawPreviousHandleOffset)"
}
/**
* Verify that the selection is truly collapsed.
*
* If the selection is contained within one selectable, this simply checks if the offsets are equal.
*
* If the Selection spans multiple selectables, then this will verify that every selected selectable
* contains a zero-width selection.
*/
internal fun Selection?.isCollapsed(layout: SelectionLayout?): Boolean {
this ?: return true
layout ?: return true
// Selection is within one selectable, simply check if the offsets are the same.
if (start.selectableId == end.selectableId) {
return start.offset == end.offset
}
// check that maxAnchor offset is 0, else the selection cannot be collapsed.
val maxAnchor = if (handlesCrossed) start else end
if (maxAnchor.offset != 0) {
return false
}
// check that the minAnchor offset is equal to the length of the text,
// else the selection is not collapsed
val minAnchor = if (handlesCrossed) end else start
if (layout.firstInfo.textLength != minAnchor.offset) {
return false
}
// Every selectable between the min and max must have empty text,
// else there is some text selected.
var allTextsEmpty = true
layout.forEachMiddleInfo {
if (it.inputText.isNotEmpty()) {
allTextsEmpty = false
}
}
return allTextsEmpty
}
internal fun <T> createSubSelections(
selection: Selection,
sortedItems: List<T>,
getId: (T) -> Long,
getSelectAll: (T, handlesCrossed: Boolean) -> Selection?,
createBoundarySelection:
(item: T, isStart: Boolean, offset: Int, handlesCrossed: Boolean) -> Selection?,
): LongObjectMap<Selection> {
val startId = selection.start.selectableId
val endId = selection.end.selectableId
if (startId == endId) {
return longObjectMapOf(startId, selection)
}
val startIndex = sortedItems.indexOfFirst { getId(it) == startId }
val endIndex = sortedItems.indexOfFirst { getId(it) == endId }
if (startIndex == -1 || endIndex == -1) {
return emptyLongObjectMap()
}
val firstIndex = minOf(startIndex, endIndex)
val lastIndex = maxOf(startIndex, endIndex)
val handlesCrossed = startIndex > endIndex
val result = mutableLongObjectMapOf<Selection>()
for (i in firstIndex..lastIndex) {
val item = sortedItems[i]
val id = getId(item)
val subSelection =
when (id) {
startId ->
createBoundarySelection(item, true, selection.start.offset, handlesCrossed)
endId -> createBoundarySelection(item, false, selection.end.offset, handlesCrossed)
else -> getSelectAll(item, handlesCrossed)
}
subSelection?.let { result[id] = it }
}
return result
}
@@ -1,3 +1,9 @@
// VENDOR-REIMPL: compose/foundation/foundation/src/skikoMain/kotlin/androidx/compose/foundation/Clickable.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.foundation package androidx.compose.foundation
import androidx.compose.ui.node.DelegatableNode import androidx.compose.ui.node.DelegatableNode
@@ -1,3 +1,9 @@
// VENDOR-REIMPL: compose/foundation/foundation/src/skikoMain/kotlin/androidx/compose/foundation/DarkTheme.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.foundation package androidx.compose.foundation
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -1,4 +1,4 @@
// VENDOR-BASE: compose/foundation/foundation/src/skikoMain/kotlin/androidx/compose/foundation/Scrollbar.skiko.kt @ v1.12.0-beta03+dev4483 // VENDOR-BASE: compose/foundation/foundation/src/skikoMain/kotlin/androidx/compose/foundation/Scrollbar.skiko.kt @ v1.12.0
// MANUAL VENDOR: refused in compose-fork.txt (flat native source set). Only edit vs base is the // MANUAL VENDOR: refused in compose-fork.txt (flat native source set). Only edit vs base is the
// K2 @file:Suppress below - identical to what sync.py injects into src/vendor .kt (this file lives // K2 @file:Suppress below - identical to what sync.py injects into src/vendor .kt (this file lives
// in src/nativeMain so sync doesn't regenerate it). Needed so compileNativeMainKotlinMetadata (the // in src/nativeMain so sync doesn't regenerate it). Needed so compileNativeMainKotlinMetadata (the
@@ -14,6 +14,12 @@
* limitations under the License. * limitations under the License.
*/ */
// VENDOR-REIMPL: compose/foundation/foundation/src/skikoMain/kotlin/androidx/compose/foundation/draganddrop/DragAndDropSource.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.foundation.draganddrop package androidx.compose.foundation.draganddrop
import androidx.compose.foundation.gestures.detectDragGestures import androidx.compose.foundation.gestures.detectDragGestures
@@ -1,3 +1,9 @@
// VENDOR-REIMPL: compose/foundation/foundation/src/skikoMain/kotlin/androidx/compose/foundation/text/StringHelpers.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.foundation.text package androidx.compose.foundation.text
// ================== // ==================
@@ -1,4 +1,4 @@
// VENDOR-BASE: compose/foundation/foundation/src/skikoMain/kotlin/androidx/compose/foundation/v2/Scrollbar.skiko.kt @ v1.12.0-beta03+dev4483 // VENDOR-BASE: compose/foundation/foundation/src/skikoMain/kotlin/androidx/compose/foundation/v2/Scrollbar.skiko.kt @ v1.12.0
// MANUAL VENDOR: expect fun runBlockingIfPossible inlined to runBlocking (flat native source set can't hold expect+actual together). // MANUAL VENDOR: expect fun runBlockingIfPossible inlined to runBlocking (flat native source set can't hold expect+actual together).
// Also carries the K2 @file:Suppress below (same as sync.py injects into src/vendor) so the native metadata compile / Windows publish accepts the orphaned JVM annotation. // Also carries the K2 @file:Suppress below (same as sync.py injects into src/vendor) so the native metadata compile / Windows publish accepts the orphaned JVM annotation.
/* /*
@@ -28,8 +28,8 @@ kotlin {
dependencies { dependencies {
// ripple imports androidx.compose.foundation.* (Indication) and // ripple imports androidx.compose.foundation.* (Indication) and
// androidx.compose.animation.core.* (RippleAnimation); ui/runtime arrive transitively. // androidx.compose.animation.core.* (RippleAnimation); ui/runtime arrive transitively.
api(project(":foundation")) api(project(":compose:foundation:foundation"))
api(project(":animation-core")) api(project(":compose:animation:animation-core"))
} }
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
} }
+6 -6
View File
@@ -30,16 +30,16 @@ kotlin {
// :ui provides ui / ui-text / runtime; :foundation provides foundation.* + // :ui provides ui / ui-text / runtime; :foundation provides foundation.* +
// (transitively) animation.* + foundation.layout.*; :animation-core provides // (transitively) animation.* + foundation.layout.*; :animation-core provides
// animation.core.*; :material-ripple provides material.ripple.*. // animation.core.*; :material-ripple provides material.ripple.*.
api(project(":ui")) api(project(":compose:ui:ui"))
api(project(":foundation")) api(project(":compose:foundation:foundation"))
api(project(":animation-core")) api(project(":compose:animation:animation-core"))
api(project(":material-ripple")) api(project(":compose:material:material-ripple"))
// androidx.collection is used by material3 internals (MutableIntObjectMap, …). // androidx.collection is used by material3 internals (MutableIntObjectMap, …).
// Already on the classpath via :ui'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(libs.androidx.collection)
// androidx.graphics.shapes.* - MaterialShapes (RoundedPolygon / // androidx.graphics.shapes.* - MaterialShapes (RoundedPolygon /
// Morph / CornerRounding) that WavyProgress / LoadingIndicator use. // Morph / CornerRounding) that WavyProgress / LoadingIndicator use.
implementation("androidx.graphics:graphics-shapes:1.1.0") implementation(libs.androidx.graphics.shapes)
// kotlinx.datetime - DatePicker / TimePicker / CalendarModel. // kotlinx.datetime - DatePicker / TimePicker / CalendarModel.
implementation(libs.kotlinx.datetime) implementation(libs.kotlinx.datetime)
} }
+2 -2
View File
@@ -14,8 +14,8 @@ kotlin {
commonMain { commonMain {
dependencies { dependencies {
api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}") api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}")
api("androidx.navigationevent:navigationevent-compose:1.1.2") api(libs.androidx.navigationevent.compose)
api(project(":ui-util")) api(project(":compose:ui:ui-util"))
implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.coroutines.core)
} }
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
+1 -1
View File
@@ -14,7 +14,7 @@ kotlin {
commonMain { commonMain {
dependencies { dependencies {
api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}") api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}")
api(project(":ui-util")) api(project(":compose:ui:ui-util"))
} }
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
} }
@@ -333,6 +333,8 @@ abstract interface androidx.compose.ui.graphics/Shape { // androidx.compose.ui.g
abstract interface com.compose.sdl.graphics/EncodedImageDecoder { // com.compose.sdl.graphics/EncodedImageDecoder|null[0] abstract interface com.compose.sdl.graphics/EncodedImageDecoder { // com.compose.sdl.graphics/EncodedImageDecoder|null[0]
abstract fun decode(kotlin/ByteArray): androidx.compose.ui.graphics/ImageBitmap? // com.compose.sdl.graphics/EncodedImageDecoder.decode|decode(kotlin.ByteArray){}[0] abstract fun decode(kotlin/ByteArray): androidx.compose.ui.graphics/ImageBitmap? // com.compose.sdl.graphics/EncodedImageDecoder.decode|decode(kotlin.ByteArray){}[0]
open fun decodeSvgAt(kotlin/ByteArray, kotlin/Int, kotlin/Int): androidx.compose.ui.graphics/ImageBitmap? // com.compose.sdl.graphics/EncodedImageDecoder.decodeSvgAt|decodeSvgAt(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
open fun svgIntrinsicSize(kotlin/ByteArray): androidx.compose.ui.geometry/Size? // com.compose.sdl.graphics/EncodedImageDecoder.svgIntrinsicSize|svgIntrinsicSize(kotlin.ByteArray){}[0]
} }
abstract interface com.compose.sdl.graphics/NativeFinishableCanvas { // com.compose.sdl.graphics/NativeFinishableCanvas|null[0] abstract interface com.compose.sdl.graphics/NativeFinishableCanvas { // com.compose.sdl.graphics/NativeFinishableCanvas|null[0]
@@ -1090,6 +1092,8 @@ final class com.compose.sdl.renderer.skia/SkiaEncodedImageDecoder : com.compose.
constructor <init>() // com.compose.sdl.renderer.skia/SkiaEncodedImageDecoder.<init>|<init>(){}[0] constructor <init>() // com.compose.sdl.renderer.skia/SkiaEncodedImageDecoder.<init>|<init>(){}[0]
final fun decode(kotlin/ByteArray): androidx.compose.ui.graphics/ImageBitmap? // com.compose.sdl.renderer.skia/SkiaEncodedImageDecoder.decode|decode(kotlin.ByteArray){}[0] final fun decode(kotlin/ByteArray): androidx.compose.ui.graphics/ImageBitmap? // com.compose.sdl.renderer.skia/SkiaEncodedImageDecoder.decode|decode(kotlin.ByteArray){}[0]
final fun decodeSvgAt(kotlin/ByteArray, kotlin/Int, kotlin/Int): androidx.compose.ui.graphics/ImageBitmap? // com.compose.sdl.renderer.skia/SkiaEncodedImageDecoder.decodeSvgAt|decodeSvgAt(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
final fun svgIntrinsicSize(kotlin/ByteArray): androidx.compose.ui.geometry/Size? // com.compose.sdl.renderer.skia/SkiaEncodedImageDecoder.svgIntrinsicSize|svgIntrinsicSize(kotlin.ByteArray){}[0]
} }
final class com.compose.sdl.renderer.skia/SkiaImageCache { // com.compose.sdl.renderer.skia/SkiaImageCache|null[0] final class com.compose.sdl.renderer.skia/SkiaImageCache { // com.compose.sdl.renderer.skia/SkiaImageCache|null[0]
@@ -2445,7 +2449,9 @@ final fun com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_MoveTo$s
final fun com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_QuadTo$stableprop_getter(): kotlin/Int // com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_QuadTo$stableprop_getter|com_compose_sdl_graphics_PathCommand_QuadTo$stableprop_getter(){}[0] final fun com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_QuadTo$stableprop_getter(): kotlin/Int // com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_QuadTo$stableprop_getter|com_compose_sdl_graphics_PathCommand_QuadTo$stableprop_getter(){}[0]
final fun com.compose.sdl.graphics/createGraphicsContext(): androidx.compose.ui.graphics/GraphicsContext // com.compose.sdl.graphics/createGraphicsContext|createGraphicsContext(){}[0] final fun com.compose.sdl.graphics/createGraphicsContext(): androidx.compose.ui.graphics/GraphicsContext // com.compose.sdl.graphics/createGraphicsContext|createGraphicsContext(){}[0]
final fun com.compose.sdl.graphics/decodeEncodedImageBitmap(kotlin/ByteArray): androidx.compose.ui.graphics/ImageBitmap? // com.compose.sdl.graphics/decodeEncodedImageBitmap|decodeEncodedImageBitmap(kotlin.ByteArray){}[0] final fun com.compose.sdl.graphics/decodeEncodedImageBitmap(kotlin/ByteArray): androidx.compose.ui.graphics/ImageBitmap? // com.compose.sdl.graphics/decodeEncodedImageBitmap|decodeEncodedImageBitmap(kotlin.ByteArray){}[0]
final fun com.compose.sdl.graphics/decodeSvgAt(kotlin/ByteArray, kotlin/Int, kotlin/Int): androidx.compose.ui.graphics/ImageBitmap? // com.compose.sdl.graphics/decodeSvgAt|decodeSvgAt(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
final fun com.compose.sdl.graphics/prepareLayerTransformationMatrix(androidx.compose.ui.graphics/Matrix, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float) // com.compose.sdl.graphics/prepareLayerTransformationMatrix|prepareLayerTransformationMatrix(androidx.compose.ui.graphics.Matrix;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float){}[0] final fun com.compose.sdl.graphics/prepareLayerTransformationMatrix(androidx.compose.ui.graphics/Matrix, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float) // com.compose.sdl.graphics/prepareLayerTransformationMatrix|prepareLayerTransformationMatrix(androidx.compose.ui.graphics.Matrix;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float){}[0]
final fun com.compose.sdl.graphics/svgIntrinsicSize(kotlin/ByteArray): androidx.compose.ui.geometry/Size? // com.compose.sdl.graphics/svgIntrinsicSize|svgIntrinsicSize(kotlin.ByteArray){}[0]
final fun com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaEncodedImageDecoder$stableprop_getter(): kotlin/Int // com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaEncodedImageDecoder$stableprop_getter|com_compose_sdl_renderer_skia_SkiaEncodedImageDecoder$stableprop_getter(){}[0] final fun com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaEncodedImageDecoder$stableprop_getter(): kotlin/Int // com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaEncodedImageDecoder$stableprop_getter|com_compose_sdl_renderer_skia_SkiaEncodedImageDecoder$stableprop_getter(){}[0]
final fun com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaImageCache$stableprop_getter(): kotlin/Int // com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaImageCache$stableprop_getter|com_compose_sdl_renderer_skia_SkiaImageCache$stableprop_getter(){}[0] final fun com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaImageCache$stableprop_getter(): kotlin/Int // com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaImageCache$stableprop_getter|com_compose_sdl_renderer_skia_SkiaImageCache$stableprop_getter(){}[0]
final fun com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaLeafDrawer$stableprop_getter(): kotlin/Int // com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaLeafDrawer$stableprop_getter|com_compose_sdl_renderer_skia_SkiaLeafDrawer$stableprop_getter(){}[0] final fun com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaLeafDrawer$stableprop_getter(): kotlin/Int // com.compose.sdl.renderer.skia/com_compose_sdl_renderer_skia_SkiaLeafDrawer$stableprop_getter|com_compose_sdl_renderer_skia_SkiaLeafDrawer$stableprop_getter(){}[0]
+4 -4
View File
@@ -24,9 +24,9 @@ kotlin {
commonMain { commonMain {
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
dependencies { dependencies {
api(project(":ui-geometry")) api(project(":compose:ui:ui-geometry"))
api(project(":ui-unit")) api(project(":compose:ui:ui-unit"))
api(project(":ui-util")) api(project(":compose:ui:ui-util"))
api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}") api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}")
implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.coroutines.core)
// androidx.collection comes transitively via :ui-util (api). // androidx.collection comes transitively via :ui-util (api).
@@ -55,7 +55,7 @@ kotlin {
kotlin.srcDir("src/skikoRendererMain/kotlin") kotlin.srcDir("src/skikoRendererMain/kotlin")
kotlin.srcDir("src/vendor/skikoRenderer/kotlin") kotlin.srcDir("src/vendor/skikoRenderer/kotlin")
dependencies { dependencies {
implementation("com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse("0.150.1-mingw.1")}") implementation("com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse(libs.versions.skikoMingw.get())}")
} }
} }
val skikoRendererMingwMain = create("skikoRendererMingwMain") { dependsOn(skikoRendererMingwSharedMain) } val skikoRendererMingwMain = create("skikoRendererMingwMain") { dependsOn(skikoRendererMingwSharedMain) }
@@ -12,7 +12,7 @@ import kotlin.math.abs
// vendored Matrices.skiko.kt and would not be visible up here. Distinct name // vendored Matrices.skiko.kt and would not be visible up here. Distinct name
// avoids clashing with that copy on the Skia leg. (RENDERER.md P1.5 will // avoids clashing with that copy on the Skia leg. (RENDERER.md P1.5 will
// reverse this rename once B2 vendors Matrices.skiko onto the Skia leg.) // reverse this rename once B2 vendors Matrices.skiko onto the Skia leg.)
// VENDOR-BASE: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/graphics/Matrices.skiko.kt @ v1.12.0-beta03+dev4483 // VENDOR-BASE: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/graphics/Matrices.skiko.kt @ v1.12.0
// 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.
@@ -15,7 +15,7 @@
*/ */
// 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
// ONLY change vs upstream: this class also implements the port draw contracts // ONLY change vs upstream: this class also implements the port draw contracts
// (NativePainterCanvas / NativeShadowCanvas / NativeFinishableCanvas) so the // (NativePainterCanvas / NativeShadowCanvas / NativeFinishableCanvas) so the
// resource-image cache + elevation shadows keep working on the Skia renderer, // resource-image cache + elevation shadows keep working on the Skia renderer,
@@ -17,7 +17,7 @@
*/ */
// 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/SkiaImageAsset.skiko.kt @ v1.12.0-beta03+dev4483 // VENDOR-BASE: compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaImageAsset.skiko.kt @ v1.12.0
// FLATTENED for our single-native-source-set layout: upstream splits Image.toBitmap / // FLATTENED for our single-native-source-set layout: upstream splits Image.toBitmap /
// ByteArray.putBytesInto into expect (here) + actual (skikoExcludingWebMain / nativeMain). // ByteArray.putBytesInto into expect (here) + actual (skikoExcludingWebMain / nativeMain).
// Those collapse into the same skikoRenderer source set here, which is illegal, so the two // Those collapse into the same skikoRenderer source set here, which is illegal, so the two
+4 -4
View File
@@ -23,9 +23,9 @@ kotlin {
commonMain { commonMain {
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
dependencies { dependencies {
api(project(":ui-graphics")) api(project(":compose:ui:ui-graphics"))
api(project(":ui-unit")) api(project(":compose:ui:ui-unit"))
api(project(":ui-util")) api(project(":compose:ui:ui-util"))
api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}") api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}")
api("org.jetbrains.compose.runtime:runtime-saveable:${libs.versions.composeRuntime.get()}") api("org.jetbrains.compose.runtime:runtime-saveable:${libs.versions.composeRuntime.get()}")
implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.coroutines.core)
@@ -54,7 +54,7 @@ kotlin {
kotlin.srcDir("src/skikoRendererMain/kotlin") kotlin.srcDir("src/skikoRendererMain/kotlin")
kotlin.srcDir("src/vendor/skikoRenderer/kotlin") kotlin.srcDir("src/vendor/skikoRenderer/kotlin")
dependencies { dependencies {
implementation("com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse("0.150.1-mingw.1")}") implementation("com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse(libs.versions.skikoMingw.get())}")
} }
} }
val skikoRendererMingwMain = create("skikoRendererMingwMain") { dependsOn(skikoRendererMingwSharedMain) } val skikoRendererMingwMain = create("skikoRendererMingwMain") { dependsOn(skikoRendererMingwSharedMain) }
@@ -6,7 +6,7 @@
* compose/ui/compose-fork.txt is commented out so this file survives * compose/ui/compose-fork.txt is commented out so this file survives
* `scripts/compose-fork/sync.sh`. * `scripts/compose-fork/sync.sh`.
*/ */
// VENDOR-BASE: compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/platform/Synchronization.kt @ v1.12.0-beta03+dev4483 // VENDOR-BASE: compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/platform/Synchronization.kt @ v1.12.0
package androidx.compose.ui.text.platform package androidx.compose.ui.text.platform
@@ -2,7 +2,7 @@ package androidx.compose.ui.text
import kotlin.experimental.ExperimentalNativeApi import kotlin.experimental.ExperimentalNativeApi
// VENDOR-BASE: compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/FontRasterizationSettings.skiko.kt @ v1.12.0-beta03+dev4483 // VENDOR-BASE: compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/FontRasterizationSettings.skiko.kt @ v1.12.0
// ================== // ==================
// MARK: FontRasterizationSettings native actual (Skia-free) // MARK: FontRasterizationSettings native actual (Skia-free)
@@ -6,6 +6,12 @@
* (verbatim copy of upstream Synchronization.skiko.kt for K2 diag test) * (verbatim copy of upstream Synchronization.skiko.kt for K2 diag test)
*/ */
// VENDOR-REIMPL: compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/Synchronization.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.ui.text.platform package androidx.compose.ui.text.platform
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
@@ -434,6 +434,14 @@ internal class SkiaParagraphOps(
// Per-run line height (upstream: res.height = lineHeight / fontSize), set only // Per-run line height (upstream: res.height = lineHeight / fontSize), set only
// when lineHeight is specified so untouched text keeps skiko's default spacing. // when lineHeight is specified so untouched text keeps skiko's default spacing.
resolveLineHeightPx(sizePx)?.let { ts.height = it / sizePx } resolveLineHeightPx(sizePx)?.let { ts.height = it / sizePx }
// How the EXTRA leading (lineHeight - fontSize) splits above vs below the
// glyphs. Mirrors upstream ParagraphBuilder.skiko.kt `res.topRatio = topRatio`.
// Without this, skiko keeps its own default (-1 = proportional to the font's
// ascent:descent), which for a line box much taller than the glyphs pushes them
// visibly DOWN - while Material 3's type styles ask for Alignment.Center. The
// fallback is Proportional, matching upstream, so text that specifies no
// lineHeightStyle is unaffected.
ts.topRatio = (style.lineHeightStyle?.alignment ?: LineHeightStyle.Alignment.Proportional).topRatio
// Span/base background fill behind the run. // Span/base background fill behind the run.
if (background.isSpecified) ts.background = SkPaint().also { it.color = background.toArgb() } if (background.isSpecified) ts.background = SkPaint().also { it.color = background.toArgb() }
// Register + resolve to a provider alias so skiko's shaper maps codepoints // Register + resolve to a provider alias so skiko's shaper maps codepoints
+2 -2
View File
@@ -14,8 +14,8 @@ kotlin {
commonMain { commonMain {
dependencies { dependencies {
api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}") api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}")
api(project(":ui-geometry")) api(project(":compose:ui:ui-geometry"))
api(project(":ui-util")) api(project(":compose:ui:ui-util"))
} }
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
} }
+1 -1
View File
@@ -16,7 +16,7 @@ kotlin {
commonMain { commonMain {
dependencies { dependencies {
api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}") api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}")
api("androidx.collection:collection:1.5.0") api(libs.androidx.collection)
} }
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
} }
+12 -9
View File
@@ -2789,16 +2789,16 @@ final class androidx.compose.ui/CombinedModifier : androidx.compose.ui/Modifier
} }
final class com.compose.sdl.input/LegacyPointerEvent { // com.compose.sdl.input/LegacyPointerEvent|null[0] final class com.compose.sdl.input/LegacyPointerEvent { // com.compose.sdl.input/LegacyPointerEvent|null[0]
constructor <init>(kotlin/Int, kotlin/Int, androidx.compose.ui.input.pointer/PointerEventType, androidx.compose.ui.input.pointer/PointerButton = ...) // com.compose.sdl.input/LegacyPointerEvent.<init>|<init>(kotlin.Int;kotlin.Int;androidx.compose.ui.input.pointer.PointerEventType;androidx.compose.ui.input.pointer.PointerButton){}[0] constructor <init>(kotlin/Float, kotlin/Float, androidx.compose.ui.input.pointer/PointerEventType, androidx.compose.ui.input.pointer/PointerButton = ...) // com.compose.sdl.input/LegacyPointerEvent.<init>|<init>(kotlin.Float;kotlin.Float;androidx.compose.ui.input.pointer.PointerEventType;androidx.compose.ui.input.pointer.PointerButton){}[0]
final val button // com.compose.sdl.input/LegacyPointerEvent.button|{}button[0] final val button // com.compose.sdl.input/LegacyPointerEvent.button|{}button[0]
final fun <get-button>(): androidx.compose.ui.input.pointer/PointerButton // com.compose.sdl.input/LegacyPointerEvent.button.<get-button>|<get-button>(){}[0] final fun <get-button>(): androidx.compose.ui.input.pointer/PointerButton // com.compose.sdl.input/LegacyPointerEvent.button.<get-button>|<get-button>(){}[0]
final val type // com.compose.sdl.input/LegacyPointerEvent.type|{}type[0] final val type // com.compose.sdl.input/LegacyPointerEvent.type|{}type[0]
final fun <get-type>(): androidx.compose.ui.input.pointer/PointerEventType // com.compose.sdl.input/LegacyPointerEvent.type.<get-type>|<get-type>(){}[0] final fun <get-type>(): androidx.compose.ui.input.pointer/PointerEventType // com.compose.sdl.input/LegacyPointerEvent.type.<get-type>|<get-type>(){}[0]
final val x // com.compose.sdl.input/LegacyPointerEvent.x|{}x[0] final val x // com.compose.sdl.input/LegacyPointerEvent.x|{}x[0]
final fun <get-x>(): kotlin/Int // com.compose.sdl.input/LegacyPointerEvent.x.<get-x>|<get-x>(){}[0] final fun <get-x>(): kotlin/Float // com.compose.sdl.input/LegacyPointerEvent.x.<get-x>|<get-x>(){}[0]
final val y // com.compose.sdl.input/LegacyPointerEvent.y|{}y[0] final val y // com.compose.sdl.input/LegacyPointerEvent.y|{}y[0]
final fun <get-y>(): kotlin/Int // com.compose.sdl.input/LegacyPointerEvent.y.<get-y>|<get-y>(){}[0] final fun <get-y>(): kotlin/Float // com.compose.sdl.input/LegacyPointerEvent.y.<get-y>|<get-y>(){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl.input/LegacyPointerEvent.equals|equals(kotlin.Any?){}[0] final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl.input/LegacyPointerEvent.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // com.compose.sdl.input/LegacyPointerEvent.hashCode|hashCode(){}[0] final fun hashCode(): kotlin/Int // com.compose.sdl.input/LegacyPointerEvent.hashCode|hashCode(){}[0]
@@ -4136,7 +4136,7 @@ sealed class com.compose.sdl/AppEvent { // com.compose.sdl/AppEvent|null[0]
} }
final class MouseWheel : com.compose.sdl/AppEvent { // com.compose.sdl/AppEvent.MouseWheel|null[0] final class MouseWheel : com.compose.sdl/AppEvent { // com.compose.sdl/AppEvent.MouseWheel|null[0]
constructor <init>(kotlin/Int, kotlin/Int, kotlin/Float, kotlin/Float, kotlin/UInt = ...) // com.compose.sdl/AppEvent.MouseWheel.<init>|<init>(kotlin.Int;kotlin.Int;kotlin.Float;kotlin.Float;kotlin.UInt){}[0] constructor <init>(kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/UInt = ...) // com.compose.sdl/AppEvent.MouseWheel.<init>|<init>(kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.UInt){}[0]
final val deltaX // com.compose.sdl/AppEvent.MouseWheel.deltaX|{}deltaX[0] final val deltaX // com.compose.sdl/AppEvent.MouseWheel.deltaX|{}deltaX[0]
final fun <get-deltaX>(): kotlin/Float // com.compose.sdl/AppEvent.MouseWheel.deltaX.<get-deltaX>|<get-deltaX>(){}[0] final fun <get-deltaX>(): kotlin/Float // com.compose.sdl/AppEvent.MouseWheel.deltaX.<get-deltaX>|<get-deltaX>(){}[0]
@@ -4145,16 +4145,16 @@ sealed class com.compose.sdl/AppEvent { // com.compose.sdl/AppEvent|null[0]
final val windowId // com.compose.sdl/AppEvent.MouseWheel.windowId|{}windowId[0] final val windowId // com.compose.sdl/AppEvent.MouseWheel.windowId|{}windowId[0]
final fun <get-windowId>(): kotlin/UInt // com.compose.sdl/AppEvent.MouseWheel.windowId.<get-windowId>|<get-windowId>(){}[0] final fun <get-windowId>(): kotlin/UInt // com.compose.sdl/AppEvent.MouseWheel.windowId.<get-windowId>|<get-windowId>(){}[0]
final val x // com.compose.sdl/AppEvent.MouseWheel.x|{}x[0] final val x // com.compose.sdl/AppEvent.MouseWheel.x|{}x[0]
final fun <get-x>(): kotlin/Int // com.compose.sdl/AppEvent.MouseWheel.x.<get-x>|<get-x>(){}[0] final fun <get-x>(): kotlin/Float // com.compose.sdl/AppEvent.MouseWheel.x.<get-x>|<get-x>(){}[0]
final val y // com.compose.sdl/AppEvent.MouseWheel.y|{}y[0] final val y // com.compose.sdl/AppEvent.MouseWheel.y|{}y[0]
final fun <get-y>(): kotlin/Int // com.compose.sdl/AppEvent.MouseWheel.y.<get-y>|<get-y>(){}[0] final fun <get-y>(): kotlin/Float // com.compose.sdl/AppEvent.MouseWheel.y.<get-y>|<get-y>(){}[0]
final fun component1(): kotlin/Int // com.compose.sdl/AppEvent.MouseWheel.component1|component1(){}[0] final fun component1(): kotlin/Float // com.compose.sdl/AppEvent.MouseWheel.component1|component1(){}[0]
final fun component2(): kotlin/Int // com.compose.sdl/AppEvent.MouseWheel.component2|component2(){}[0] final fun component2(): kotlin/Float // com.compose.sdl/AppEvent.MouseWheel.component2|component2(){}[0]
final fun component3(): kotlin/Float // com.compose.sdl/AppEvent.MouseWheel.component3|component3(){}[0] final fun component3(): kotlin/Float // com.compose.sdl/AppEvent.MouseWheel.component3|component3(){}[0]
final fun component4(): kotlin/Float // com.compose.sdl/AppEvent.MouseWheel.component4|component4(){}[0] final fun component4(): kotlin/Float // com.compose.sdl/AppEvent.MouseWheel.component4|component4(){}[0]
final fun component5(): kotlin/UInt // com.compose.sdl/AppEvent.MouseWheel.component5|component5(){}[0] final fun component5(): kotlin/UInt // com.compose.sdl/AppEvent.MouseWheel.component5|component5(){}[0]
final fun copy(kotlin/Int = ..., kotlin/Int = ..., kotlin/Float = ..., kotlin/Float = ..., kotlin/UInt = ...): com.compose.sdl/AppEvent.MouseWheel // com.compose.sdl/AppEvent.MouseWheel.copy|copy(kotlin.Int;kotlin.Int;kotlin.Float;kotlin.Float;kotlin.UInt){}[0] final fun copy(kotlin/Float = ..., kotlin/Float = ..., kotlin/Float = ..., kotlin/Float = ..., kotlin/UInt = ...): com.compose.sdl/AppEvent.MouseWheel // com.compose.sdl/AppEvent.MouseWheel.copy|copy(kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.UInt){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl/AppEvent.MouseWheel.equals|equals(kotlin.Any?){}[0] final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl/AppEvent.MouseWheel.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // com.compose.sdl/AppEvent.MouseWheel.hashCode|hashCode(){}[0] final fun hashCode(): kotlin/Int // com.compose.sdl/AppEvent.MouseWheel.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // com.compose.sdl/AppEvent.MouseWheel.toString|toString(){}[0] final fun toString(): kotlin/String // com.compose.sdl/AppEvent.MouseWheel.toString|toString(){}[0]
@@ -4542,6 +4542,9 @@ final object com.compose.sdl.platform/DefaultViewConfiguration : androidx.compos
} }
final object com.compose.sdl.text.input/ImeBridge { // com.compose.sdl.text.input/ImeBridge|null[0] final object com.compose.sdl.text.input/ImeBridge { // com.compose.sdl.text.input/ImeBridge|null[0]
final var onSessionActiveChange // com.compose.sdl.text.input/ImeBridge.onSessionActiveChange|{}onSessionActiveChange[0]
final fun <get-onSessionActiveChange>(): kotlin/Function1<kotlin/Boolean, kotlin/Unit>? // com.compose.sdl.text.input/ImeBridge.onSessionActiveChange.<get-onSessionActiveChange>|<get-onSessionActiveChange>(){}[0]
final fun <set-onSessionActiveChange>(kotlin/Function1<kotlin/Boolean, kotlin/Unit>?) // com.compose.sdl.text.input/ImeBridge.onSessionActiveChange.<set-onSessionActiveChange>|<set-onSessionActiveChange>(kotlin.Function1<kotlin.Boolean,kotlin.Unit>?){}[0]
final var request // com.compose.sdl.text.input/ImeBridge.request|{}request[0] final var request // com.compose.sdl.text.input/ImeBridge.request|{}request[0]
final fun <get-request>(): androidx.compose.ui.platform/PlatformTextInputMethodRequest? // com.compose.sdl.text.input/ImeBridge.request.<get-request>|<get-request>(){}[0] final fun <get-request>(): androidx.compose.ui.platform/PlatformTextInputMethodRequest? // com.compose.sdl.text.input/ImeBridge.request.<get-request>|<get-request>(){}[0]
+13 -13
View File
@@ -42,22 +42,22 @@ kotlin {
// scripts/compose-fork/sync.sh. Never hand-edit; re-run sync. // scripts/compose-fork/sync.sh. Never hand-edit; re-run sync.
kotlin.srcDir("src/vendor/common/kotlin") kotlin.srcDir("src/vendor/common/kotlin")
dependencies { dependencies {
api(project(":ui-util")) api(project(":compose:ui:ui-util"))
api(project(":ui-geometry")) api(project(":compose:ui:ui-geometry"))
api(project(":ui-graphics")) api(project(":compose:ui:ui-graphics"))
api(project(":ui-text")) api(project(":compose:ui:ui-text"))
api(project(":ui-unit")) api(project(":compose:ui:ui-unit"))
api(project(":ui-backhandler")) api(project(":compose:ui:ui-backhandler"))
api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}") api("org.jetbrains.compose.runtime:runtime:${libs.versions.composeRuntime.get()}")
api("org.jetbrains.compose.runtime:runtime-saveable:${libs.versions.composeRuntime.get()}") api("org.jetbrains.compose.runtime:runtime-saveable:${libs.versions.composeRuntime.get()}")
api("androidx.compose.runtime:runtime-retain:${libs.versions.composeRuntime.get()}") api("androidx.compose.runtime:runtime-retain:${libs.versions.composeRuntime.get()}")
api("androidx.navigationevent:navigationevent-compose:1.1.2") api(libs.androidx.navigationevent.compose)
api("androidx.savedstate:savedstate:1.5.0") api(libs.androidx.savedstate)
api("androidx.savedstate:savedstate-compose:1.5.0") api(libs.androidx.savedstate.compose)
api("androidx.lifecycle:lifecycle-viewmodel-compose:2.11.0") api("androidx.lifecycle:lifecycle-viewmodel-compose:2.11.0")
api("androidx.lifecycle:lifecycle-runtime-compose:2.11.0") api("androidx.lifecycle:lifecycle-runtime-compose:2.11.0")
api("androidx.navigation3:navigation3-runtime:1.1.4") api(libs.androidx.navigation3.runtime)
api("androidx.lifecycle:lifecycle-viewmodel-navigation3:2.11.0") api(libs.androidx.lifecycle.viewmodel.navigation3)
implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.coroutines.core)
implementation(libs.okio) implementation(libs.okio)
implementation("org.jetbrains.kotlinx:atomicfu:0.23.1") implementation("org.jetbrains.kotlinx:atomicfu:0.23.1")
@@ -70,7 +70,7 @@ kotlin {
// The sdl3 cinterop now lives in :sdl-core; expose it (api) so :ui's // 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.* // SDL platform + renderer code - and :desktop-native-window downstream - see sdl3.*
// and inherit SDL3's static-lib + linker-opt propagation. // and inherit SDL3's static-lib + linker-opt propagation.
api(project(":sdl-core")) api(project(":sdl:sdl-core"))
} }
} }
@@ -106,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("com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse("0.150.1-mingw.1")}") implementation("com.bitsycore.skiko:skiko:${providers.gradleProperty("skikoMingwVersion").getOrElse(libs.versions.skikoMingw.get())}")
} }
} }
val skikoRendererMingwMain = create("skikoRendererMingwMain") { dependsOn(skikoRendererMingwSharedMain) } val skikoRendererMingwMain = create("skikoRendererMingwMain") { dependsOn(skikoRendererMingwSharedMain) }
@@ -10,7 +10,7 @@
* Line-for-line kept in sync; the entry in compose/ui/compose-fork.txt is * Line-for-line kept in sync; the entry in compose/ui/compose-fork.txt is
* commented out so this file survives `scripts/compose-fork/sync.sh`. * commented out so this file survives `scripts/compose-fork/sync.sh`.
*/ */
// VENDOR-BASE: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/Synchronization.kt @ v1.12.0-beta03+dev4483 // VENDOR-BASE: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/Synchronization.kt @ v1.12.0
package androidx.compose.ui.platform package androidx.compose.ui.platform
@@ -16,7 +16,7 @@
// MANUALLY VENDORED (NON-IDEMPOTENT) from compose-multiplatform-core: // MANUALLY VENDORED (NON-IDEMPOTENT) from compose-multiplatform-core:
// compose/ui/ui/src/skikoMain/.../node/GraphicsLayerOwnerLayer.skiko.kt // compose/ui/ui/src/skikoMain/.../node/GraphicsLayerOwnerLayer.skiko.kt
// VENDOR-BASE: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/GraphicsLayerOwnerLayer.skiko.kt @ v1.12.0-beta03+dev4483 // VENDOR-BASE: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/GraphicsLayerOwnerLayer.skiko.kt @ v1.12.0
// Change vs upstream: dropped the trailing `SkiaGraphicsContext.setLightingInfo` // Change vs upstream: dropped the trailing `SkiaGraphicsContext.setLightingInfo`
// extension + LIGHT_* constants (skiko-only shadow lighting; our shadows go via // extension + LIGHT_* constants (skiko-only shadow lighting; our shadows go via
// NativeShadowCanvas). The class body is unchanged - it is the real OwnedLayer // NativeShadowCanvas). The class body is unchanged - it is the real OwnedLayer
@@ -1,5 +1,11 @@
@file:Suppress("DEPRECATION") @file:Suppress("DEPRECATION")
// VENDOR-REIMPL: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/CompositionLocals.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.ui.platform package androidx.compose.ui.platform
import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.runtime.staticCompositionLocalOf
@@ -1,3 +1,9 @@
// VENDOR-REIMPL: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/PlatformClipboard.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.ui.platform package androidx.compose.ui.platform
import kotlinx.cinterop.ByteVar import kotlinx.cinterop.ByteVar
@@ -1,3 +1,9 @@
// VENDOR-REIMPL: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/Synchronization.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.ui.platform package androidx.compose.ui.platform
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
@@ -1,3 +1,9 @@
// VENDOR-REIMPL: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/semantics/SemanticsRegion.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.ui.semantics package androidx.compose.ui.semantics
import androidx.compose.ui.unit.IntRect import androidx.compose.ui.unit.IntRect
@@ -1,5 +1,11 @@
@file:OptIn(androidx.compose.ui.InternalComposeUiApi::class) @file:OptIn(androidx.compose.ui.InternalComposeUiApi::class)
// VENDOR-REIMPL: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/viewinterop/InteropView.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.ui.viewinterop package androidx.compose.ui.viewinterop
// Native actual for vendored commonMain InteropView.kt. Mirrors upstream // Native actual for vendored commonMain InteropView.kt. Mirrors upstream
@@ -1,3 +1,9 @@
// VENDOR-REIMPL: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/window/Dialog.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.ui.window package androidx.compose.ui.window
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -1,3 +1,9 @@
// VENDOR-REIMPL: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/window/Popup.skiko.kt @ v1.12.0
// Project REIMPLEMENTATION, not a derived copy: same package + signatures,
// different body (the port replaces upstream's skiko scene/platform layer).
// Upstream edits to the counterpart do NOT need reconciling here - re-check
// only if the expect/actual SIGNATURES change.
package androidx.compose.ui.window package androidx.compose.ui.window
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
+5 -5
View File
@@ -66,22 +66,22 @@ kotlin {
implementation("org.jetbrains.compose.material3:material3:$vComposeM3JvmVersion") implementation("org.jetbrains.compose.material3:material3:$vComposeM3JvmVersion")
// Common Material Symbols Utility // Common Material Symbols Utility
implementation(project(":material-symbols")) implementation(project(":utils:material-symbols"))
// nav3 + lifecycle: real KMP Maven artifacts on every target // nav3 + lifecycle: real KMP Maven artifacts on every target
implementation("androidx.navigation3:navigation3-runtime:1.1.4") implementation(libs.androidx.navigation3.runtime)
implementation("org.jetbrains.androidx.navigation3:navigation3-ui:1.2.0-alpha02") implementation("org.jetbrains.androidx.navigation3:navigation3-ui:1.2.0-alpha02")
implementation("androidx.lifecycle:lifecycle-viewmodel-navigation3:2.11.0") implementation(libs.androidx.lifecycle.viewmodel.navigation3)
} }
} }
nativeMain { nativeMain {
dependencies { dependencies {
implementation(project(":desktop-native-window")) implementation(project(":compose:desktop:native:desktop-native-window"))
} }
} }
jvmMain { jvmMain {
dependencies { dependencies {
implementation("androidx.navigation3:navigation3-runtime:1.2.0-alpha05") implementation(libs.androidx.navigation3.runtime)
implementation(compose.desktop.currentOs) implementation(compose.desktop.currentOs)
} }
} }
@@ -32,21 +32,11 @@ plugins {
dependencyResolutionManagement { dependencyResolutionManagement {
repositories { repositories {
maven("https://maven.bitsycore.com/releases") { // The port's own artifacts AND the bitsycore skiko fork
content { excludeGroup("com.bitsycore.skiko") } // (com.bitsycore.skiko:skiko / :skiko-mingwx64) both live here - public,
} // no credentials. Windows (mingwX64) renders through the fork; macOS and
// Windows (mingwX64) renders through the bitsycore skiko fork, published to // Linux use the official org.jetbrains.skiko from Maven Central.
// its OWN GitHub Packages repo as com.bitsycore.skiko:skiko / :skiko-mingwx64. maven("https://maven.bitsycore.com/releases")
// GitHub Packages requires authentication even for public packages.
// (macOS/Linux use the official org.jetbrains.skiko from Maven Central, so this
// repo is scoped to just the fork group.) Omit only if you build no mingwX64.
maven("https://maven.pkg.github.com/bitsycore/skiko") {
credentials {
username = providers.gradleProperty("gpr.user").orNull ?: System.getenv("GITHUB_ACTOR")
password = providers.gradleProperty("gpr.token").orNull ?: System.getenv("GITHUB_TOKEN")
}
content { includeGroup("com.bitsycore.skiko") }
}
google() google()
mavenCentral() mavenCentral()
} }
@@ -87,6 +77,44 @@ upstream), `composeRuntime`, and `version` (the port klib version being
substituted). You can still write literal versions if you prefer; the extension substituted). You can still write literal versions if you prefer; the extension
just removes the drift. just removes the drift.
### Ecosystem libraries
Substitution is not limited to Compose. Several popular libraries stop short of
Kotlin/Native desktop upstream; the port vendors them and the bridge swaps them
in on native desktop targets, so you declare the **official** coordinates and
they resolve everywhere:
```kotlin
commonMain.dependencies {
// Koin - koin-core already ships desktop-native klibs; these four are the
// ones upstream builds for apple + android only.
implementation("io.insert-koin:koin-core:4.2.2")
implementation("io.insert-koin:koin-compose:4.2.2")
implementation("io.insert-koin:koin-compose-viewmodel:4.2.2")
implementation("io.insert-koin:koin-compose-navigation3:4.2.2")
// Coil 3 - no mingwX64 upstream anywhere, and no desktop native at all for
// its compose layer.
implementation("io.coil-kt.coil3:coil-compose:3.6.2")
implementation("io.coil-kt.coil3:coil-network-ktor3:3.6.2")
implementation("io.coil-kt.coil3:coil-svg:3.6.2")
// Pulse MVI
implementation("com.bitsycore.lib:pulse:0.3.7")
implementation("com.bitsycore.lib:pulse-compose:0.3.7")
}
```
Two caveats:
- Koin's `koin-compose-viewmodel-navigation` is **not** substituted. It sits on
Navigation 2's `navigation-compose`, which publishes no mingwX64 or linux
klibs under either the `androidx.*` or `org.jetbrains.androidx.*`
coordinates. Use `koin-compose-navigation3` instead.
- Lifecycle comes from the **google** `androidx.lifecycle:*` coordinates here.
If your own build also pulls the `org.jetbrains.androidx.lifecycle:*` mirrors,
you will get the same classes twice - pick one.
### Settings-wide or per-module ### Settings-wide or per-module
The plugin applies at either level: The plugin applies at either level:
@@ -18,7 +18,18 @@ import java.util.Properties
* FULL-COMMONIZATION BRIDGE (root build.gradle.kts): ui-graphics / ui-text are * FULL-COMMONIZATION BRIDGE (root build.gradle.kts): ui-graphics / ui-text are
* their own modules (upstream layout). The runtime is deliberately absent - the * their own modules (upstream layout). The runtime is deliberately absent - the
* official org.jetbrains.compose.runtime klibs serve every target, never * official org.jetbrains.compose.runtime klibs serve every target, never
* substituted. * substituted. The table also covers the ECOSYSTEM libraries the port vendors
* (Koin, Coil 3, Pulse MVI) - see the grouped entries below.
*
* RELATIONSHIP TO THE REPO-INTERNAL FULL-COMMONIZATION BRIDGE (root
* build.gradle.kts): the two are NOT mirror images, and should not be made into
* one. This table must cover every coordinate the port PUBLISHES, because a
* consumer can declare any of them. The root build only needs a rule for the
* coordinates an IN-REPO module actually declares as a Maven coordinate in its
* commonMain; in-repo modules reach everything else through `project(...)`,
* which needs no substitution. So this table is legitimately the larger of the
* two (today: animation-graphics, material-ripple and ui-backhandler are here
* and not there). What IS an error is a published coordinate missing HERE.
*/ */
private val bridgeTable = mapOf( private val bridgeTable = mapOf(
"org.jetbrains.compose.ui:ui" to "com.bitsycore.compose.ui:ui", "org.jetbrains.compose.ui:ui" to "com.bitsycore.compose.ui:ui",
@@ -38,6 +49,37 @@ private val bridgeTable = mapOf(
"org.jetbrains.compose.material:material-ripple" to "com.bitsycore.compose.material:material-ripple", "org.jetbrains.compose.material:material-ripple" to "com.bitsycore.compose.material:material-ripple",
"org.jetbrains.compose.components:components-resources" to "com.bitsycore.compose.components:components-resources", "org.jetbrains.compose.components:components-resources" to "com.bitsycore.compose.components:components-resources",
"org.jetbrains.androidx.navigation3:navigation3-ui" to "com.bitsycore.navigation3:navigation3-ui", "org.jetbrains.androidx.navigation3:navigation3-ui" to "com.bitsycore.navigation3:navigation3-ui",
// ============
// Ecosystem libraries the port vendors because upstream stops short of
// Kotlin/Native desktop. Same deal: declare the OFFICIAL coordinate, get
// the port's klib on native desktop targets only.
// Koin. koin-core itself publishes mingwX64 + linux and is NOT substituted.
// koin-compose-viewmodel-navigation is absent on purpose: it needs nav2's
// navigation-compose, which has no mingwX64/linux klibs under either
// coordinate set - use koin-compose-navigation3.
"io.insert-koin:koin-core-viewmodel" to "com.bitsycore.koin:koin-core-viewmodel",
"io.insert-koin:koin-compose" to "com.bitsycore.koin:koin-compose",
"io.insert-koin:koin-compose-viewmodel" to "com.bitsycore.koin:koin-compose-viewmodel",
"io.insert-koin:koin-compose-navigation3" to "com.bitsycore.koin:koin-compose-navigation3",
// Coil 3 - no mingwX64 upstream anywhere, no desktop native at all for the
// compose layer.
"io.coil-kt.coil3:coil-core" to "com.bitsycore.coil3:coil-core",
"io.coil-kt.coil3:coil" to "com.bitsycore.coil3:coil",
"io.coil-kt.coil3:coil-compose-core" to "com.bitsycore.coil3:coil-compose-core",
"io.coil-kt.coil3:coil-compose" to "com.bitsycore.coil3:coil-compose",
"io.coil-kt.coil3:coil-svg" to "com.bitsycore.coil3:coil-svg",
"io.coil-kt.coil3:coil-network-core" to "com.bitsycore.coil3:coil-network-core",
"io.coil-kt.coil3:coil-network-ktor3" to "com.bitsycore.coil3:coil-network-ktor3",
// Pulse MVI. Upstream publishes com.bitsycore.lib:*; the port republishes
// under com.bitsycore.pulse:* so the two coordinates never collide.
"com.bitsycore.lib:pulse" to "com.bitsycore.pulse:pulse",
"com.bitsycore.lib:pulse-viewmodel" to "com.bitsycore.pulse:pulse-viewmodel",
"com.bitsycore.lib:pulse-savedstate" to "com.bitsycore.pulse:pulse-savedstate",
"com.bitsycore.lib:pulse-compose" to "com.bitsycore.pulse:pulse-compose",
) )
/** The K/N desktop targets the port serves; configuration names carry the token. */ /** The K/N desktop targets the port serves; configuration names carry the token. */
+12
View File
@@ -0,0 +1,12 @@
#This file is generated by updateDaemonJvm
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e8a8af69dfa4af1da101ce6dcca8a515/redirect
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/c74fd73cbb3058767955d9f6624f6d95/redirect
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e8a8af69dfa4af1da101ce6dcca8a515/redirect
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/c74fd73cbb3058767955d9f6624f6d95/redirect
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/93f3070383ac1ed4682d562fb200b9d0/redirect
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/649d77d8b90940be6e926451fcfe70ee/redirect
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e8a8af69dfa4af1da101ce6dcca8a515/redirect
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/c74fd73cbb3058767955d9f6624f6d95/redirect
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/c670ba1eded2c9693e9102e0bb673e60/redirect
toolchainVendor=ORACLE
toolchainVersion=25
+137 -26
View File
@@ -1,41 +1,152 @@
# ==========================================================================
# VERSION POLICY - read before bumping anything
# ==========================================================================
#
# 1. If Compose Multiplatform integrates it, pin what CMP ships. For the
# androidx mirrors that means the JETPACK version CMP's release notes map
# its org.jetbrains.androidx.* artifact to - the port consumes the GOOGLE
# coordinates, never the mirrors (mixing both duplicates every class).
# Do not upgrade these past CMP on a hunch: the vendored sources under
# src/vendor were compiled against them.
# 2. If CMP does not integrate it, pin the latest release.
# 3. Deliberate exceptions to (1) are allowed, but each one is COMMENTED with
# why it is safe. Today there is one: androidxSavedState.
#
# Keep in lockstep with the upstream git refs in
# scripts/compose-fork/compose.properties, and with the "Pinned versions"
# tables in README.md.
#
# ==========================================================================
[versions] [versions]
kotlin = "2.4.0"
# Official Compose Multiplatform versions the port's vendored sources track and # ============
# the JVM parity leg forces. SINGLE SOURCE: consumed by the bridge plugin # Toolchain
# (stamped into bridge-version.properties and exposed to consumers) and by
# demo / apidemo / material-symbols. Keep in lockstep with the vendored ref in # Policy 2 (not something CMP dictates): latest release. Newer than the Kotlin
# scripts/compose-fork/compose.properties on each bump. # CMP 1.12.0 is itself built with (2.3.20), which is fine - Kotlin/Native reads
# compose = ui / foundation / animation / material # older klibs, and the whole port + both sample apps compile and link clean on
# composeMaterial3 = material3 (versioned separately upstream) # 2.4.20 with no klib API diff against 2.4.0.
# composeRuntime = the official runtime klibs (never substituted) kotlin = "2.4.20"
compose = "1.12.0-beta02"
# ============
# Compose Multiplatform (CMP-pinned - policy 1)
#
# compose = ui / foundation / animation / material
# composeMaterial3 = material3, which rides its own train upstream:
# 1.12.0-alpha03 IS what CMP 1.12.0 ships
# (Jetpack material3 1.5.0-alpha22)
# composeRuntime = the official runtime klibs, never substituted
#
# Consumed by the bridge plugin (stamped into bridge-version.properties and
# exposed to consumers) and by demo / apidemo / material-symbols.
compose = "1.12.0"
composeMaterial3 = "1.12.0-alpha03" composeMaterial3 = "1.12.0-alpha03"
composeRuntime = "1.11.1" composeRuntime = "1.12.0"
# ============
# Skia
# CMP 1.12.0 pins skiko 0.150.1, so macOS/Linux use exactly that.
skiko = "0.150.1"
# The bitsycore skiko FORK for mingwX64 (skiko + Skia inside
# skiko-windows-x64.dll). Its `-mingw.N` base MUST stay equal to `skiko` above.
# Overridable per-build with -PskikoMingwVersion.
skikoMingw = "0.150.1-mingw.2"
# ============
# AndroidX (CMP-pinned - policy 1)
androidxLifecycle = "2.11.0"
androidxCollection = "1.5.0"
androidxGraphicsShapes = "1.1.0"
# CMP ships org.jetbrains.androidx.navigationevent 1.1.0 == Jetpack 1.1.1; 1.1.2
# is the latest PATCH of that same minor, so it stays inside policy 1.
androidxNavigationEvent = "1.1.2"
# CMP ships org.jetbrains.androidx.navigation3 1.2.0-alpha02 == Jetpack
# 1.2.0-alpha04. Stay exactly there: it is a pre-release line, so alpha-to-alpha
# can move API under the vendored :navigation3:navigation3-ui.
navigation3Runtime = "1.2.0-alpha04"
# EXCEPTION to policy 1, deliberate: CMP 1.12.0 builds against savedstate 1.4.0,
# and androidx.lifecycle 2.11.0 *requires* 1.4.0 - but only as a MINIMUM, so
# 1.5.0 resolves with no conflict. Taken on purpose to hand consumers the newer
# savedstate API; the delta is additive within the same major.
androidxSavedState = "1.5.0"
# ============
# Vendored ecosystem libraries (not in CMP - latest release, policy 2)
#
# These numbers double as the upstream git refs the sources are vendored from
# (KOIN_REF / COIL_REF in scripts/compose-fork/compose.properties) - bump both.
koin = "4.2.2"
coil = "3.6.2"
# ============
# Infrastructure (not in CMP - latest release, policy 2)
kotlinxCoroutines = "1.11.0" kotlinxCoroutines = "1.11.0"
kotlinxDateTime = "0.8.0" kotlinxDateTime = "0.8.0"
kotlinxSerialization = "1.11.0" kotlinxSerialization = "1.11.0"
okio = "3.17.0" kotlinxIoOkio = "0.9.1"
ktor = "3.5.1" okio = "3.18.2"
skiko = "0.150.1" ktor = "3.5.2"
[libraries] [libraries]
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" } # ============
kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinxCoroutines" } # Skia
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDateTime" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerialization" }
okio = { module = "com.squareup.okio:okio", version.ref = "okio" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-curl = { module = "io.ktor:ktor-client-curl", version.ref = "ktor" }
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
skiko = { module = "org.jetbrains.skiko:skiko", version.ref = "skiko" } skiko = { module = "org.jetbrains.skiko:skiko", version.ref = "skiko" }
# ============
# AndroidX - used AS-IS (these publish real Kotlin/Native desktop klibs, so
# nothing here is vendored or substituted). GOOGLE coordinates throughout: the
# org.jetbrains.androidx.* mirrors carry the same classes, so pulling both puts
# every class on the path twice.
androidx-collection = { module = "androidx.collection:collection", version.ref = "androidxCollection" }
androidx-graphics-shapes = { module = "androidx.graphics:graphics-shapes", version.ref = "androidxGraphicsShapes" }
androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewmodel-navigation3 = { module = "androidx.lifecycle:lifecycle-viewmodel-navigation3", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewmodel-savedstate = { module = "androidx.lifecycle:lifecycle-viewmodel-savedstate", version.ref = "androidxLifecycle" }
androidx-navigation3-runtime = { module = "androidx.navigation3:navigation3-runtime", version.ref = "navigation3Runtime" }
androidx-navigationevent-compose = { module = "androidx.navigationevent:navigationevent-compose", version.ref = "androidxNavigationEvent" }
androidx-savedstate = { module = "androidx.savedstate:savedstate", version.ref = "androidxSavedState" }
androidx-savedstate-compose = { module = "androidx.savedstate:savedstate-compose", version.ref = "androidxSavedState" }
# ============
# Koin. koin-core publishes mingwX64 + linux klibs and is consumed from Maven
# as-is; only the viewmodel / compose layers are vendored (see koin/).
koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
# ============
# Infrastructure
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" }
kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinxCoroutines" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" }
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDateTime" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerialization" }
# coil-network-ktor3 bridges ktor's kotlinx-io sinks onto okio.
kotlinx-io-okio = { module = "org.jetbrains.kotlinx:kotlinx-io-okio", version.ref = "kotlinxIoOkio" }
okio = { module = "com.squareup.okio:okio", version.ref = "okio" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
ktor-client-curl = { module = "io.ktor:ktor-client-curl", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
[plugins] [plugins]
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlin-plugin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } kotlin-plugin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlin-plugin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kotlin-plugin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
compose-multiplatform = { id = "org.jetbrains.compose", version.ref = "compose" } compose-multiplatform = { id = "org.jetbrains.compose", version.ref = "compose" }
binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.18.1" } binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.18.1" }

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