@kurot/core 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +61 -2
  2. package/README.md +45 -14
  3. package/dist/kurot/display/texture/RenderTexture.d.ts +1 -0
  4. package/dist/kurot/display/texture/RenderTexture.d.ts.map +1 -1
  5. package/dist/kurot/display/texture/RenderTexture.js +4 -0
  6. package/dist/kurot/display/texture/RenderTexture.js.map +1 -1
  7. package/dist/kurot/display/texture/SpriteSheet.d.ts +4 -0
  8. package/dist/kurot/display/texture/SpriteSheet.d.ts.map +1 -1
  9. package/dist/kurot/display/texture/SpriteSheet.js +7 -3
  10. package/dist/kurot/display/texture/SpriteSheet.js.map +1 -1
  11. package/dist/kurot/display/texture/Texture.d.ts +14 -0
  12. package/dist/kurot/display/texture/Texture.d.ts.map +1 -1
  13. package/dist/kurot/display/texture/Texture.js +28 -6
  14. package/dist/kurot/display/texture/Texture.js.map +1 -1
  15. package/dist/kurot/player/bitmap-fill.js +1 -1
  16. package/dist/kurot/player/bitmap-fill.js.map +1 -1
  17. package/dist/kurot/player/canvas/CanvasRenderer.d.ts.map +1 -1
  18. package/dist/kurot/player/canvas/CanvasRenderer.js +25 -36
  19. package/dist/kurot/player/canvas/CanvasRenderer.js.map +1 -1
  20. package/dist/kurot/player/pipes/BitmapPipe.js +2 -2
  21. package/dist/kurot/player/pipes/BitmapPipe.js.map +1 -1
  22. package/dist/kurot/player/pipes/BitmapTextPipe.d.ts.map +1 -1
  23. package/dist/kurot/player/pipes/BitmapTextPipe.js +1 -2
  24. package/dist/kurot/player/pipes/BitmapTextPipe.js.map +1 -1
  25. package/dist/kurot/player/pipes/MaskPipe.d.ts.map +1 -1
  26. package/dist/kurot/player/pipes/MaskPipe.js +7 -1
  27. package/dist/kurot/player/pipes/MaskPipe.js.map +1 -1
  28. package/dist/kurot/player/webgl/WebGLRenderer.d.ts.map +1 -1
  29. package/dist/kurot/player/webgl/WebGLRenderer.js +2 -1
  30. package/dist/kurot/player/webgl/WebGLRenderer.js.map +1 -1
  31. package/dist/kurot/resource/analyzers/SheetAnalyzer.d.ts.map +1 -1
  32. package/dist/kurot/resource/analyzers/SheetAnalyzer.js +4 -1
  33. package/dist/kurot/resource/analyzers/SheetAnalyzer.js.map +1 -1
  34. package/dist/kurot/text/BitmapFont.d.ts.map +1 -1
  35. package/dist/kurot/text/BitmapFont.js +2 -0
  36. package/dist/kurot/text/BitmapFont.js.map +1 -1
  37. package/dist/kurot/text/TextField.d.ts.map +1 -1
  38. package/dist/kurot/text/TextField.js +7 -30
  39. package/dist/kurot/text/TextField.js.map +1 -1
  40. package/dist/kurot/text/TextLineLayout.d.ts.map +1 -1
  41. package/dist/kurot/text/TextLineLayout.js +44 -6
  42. package/dist/kurot/text/TextLineLayout.js.map +1 -1
  43. package/dist/kurot/text/TextMeasurer.d.ts +5 -0
  44. package/dist/kurot/text/TextMeasurer.d.ts.map +1 -1
  45. package/dist/kurot/text/TextMeasurer.js +10 -1
  46. package/dist/kurot/text/TextMeasurer.js.map +1 -1
  47. package/dist/kurot/text/TextRenderBounds.d.ts +1 -1
  48. package/dist/kurot/text/TextRenderBounds.d.ts.map +1 -1
  49. package/dist/kurot/text/TextRenderBounds.js +9 -2
  50. package/dist/kurot/text/TextRenderBounds.js.map +1 -1
  51. package/dist/kurot/text/TextVerticalLayout.d.ts +7 -0
  52. package/dist/kurot/text/TextVerticalLayout.d.ts.map +1 -0
  53. package/dist/kurot/text/TextVerticalLayout.js +23 -0
  54. package/dist/kurot/text/TextVerticalLayout.js.map +1 -0
  55. package/dist/kurot/text/types/ITextElement.d.ts +12 -0
  56. package/dist/kurot/text/types/ITextElement.d.ts.map +1 -1
  57. package/docs/ai-context.md +24 -2
  58. package/docs/architecture.md +8 -1
  59. package/docs/bitmap-fill.md +9 -3
  60. package/docs/bitmap-fonts.md +7 -3
  61. package/docs/centered-flips.md +4 -4
  62. package/docs/resource.md +5 -0
  63. package/docs/text-layout.md +41 -0
  64. package/docs/texture-density.md +96 -0
  65. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ITextElement.d.ts","sourceRoot":"","sources":["../../../../src/kurot/text/types/ITextElement.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IAClD,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CACzB"}
1
+ {"version":3,"file":"ITextElement.d.ts","sourceRoot":"","sources":["../../../../src/kurot/text/types/ITextElement.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IAClD,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CACzB"}
@@ -1,15 +1,21 @@
1
1
  # @kurot/core — AI context map
2
2
 
3
- Source prepares 2.4.0; the released baseline below is historical. Read
3
+ Core 2.5.0 is prepared for publication, not yet published. Latest verified npm
4
+ release is 2.4.0. Read
4
5
  [centered flips](../../../docs/centered-flips.md) before changing transforms,
5
6
  reflection frames, authored flags or dependency adoption.
6
7
 
8
+ Core 2.5.0 adds independent Texture/SpriteSheet source density. Read [texture density](texture-density.md) before changing texture
9
+ dimensions or sheet loading. `resolution` defaults to 1 and is immutable;
10
+ sampling and page coordinates are physical, frame bounds/trim/grid are logical.
11
+ The default KUI kit uses 2× assets and requires this new Core implementation.
12
+
7
13
  Read this before exploring `src/`. It is a compressed map of the package so an
8
14
  agent unfamiliar with Kurot does not need to re-derive the architecture from
9
15
  scratch on every session. Treat the package source and its `src/index.ts`
10
16
  barrel as the authority for current behavior and exports.
11
17
 
12
- Package identity: `@kurot/core@2.4.0`, prepared in source and not published. It provides Kurot's scene graph,
18
+ Package identity: `@kurot/core@2.5.0`, pending publication. It provides Kurot's scene graph,
13
19
  events, rendering, text, resource, network and media runtime. Rendering uses a
14
20
  flat `InstructionSet + RenderPipe` pipeline. ES2022 / evergreen browsers only
15
21
  with `strict: true`. Two
@@ -86,6 +92,10 @@ colocated under `examples/benchmark/`; none are exported from `index.ts`.
86
92
  content, not the clip. WebGL's nested/rotated stencil path must use the same
87
93
  viewport origin as its axis-aligned scissor path. Rectangle masks retain
88
94
  their own local x/y. See `player/pipes/MaskPipe.ts`.
95
+ - The Core 2.5.0 axis-aligned WebGL scissor correction encloses fractional
96
+ physical bounds with floor(left/top) and ceil(right/bottom), then subtracts
97
+ those integer edges. Do not truncate position and size independently: this
98
+ cuts boundary pixels from scaled ItemRenderer skins. Stencil clips are unchanged.
89
99
  - `CanvasRenderer` is not purely a fallback. The WebGL backend depends on it
90
100
  internally to rasterize Graphics/Text to offscreen canvases before texture
91
101
  upload, and to snapshot `RenderTexture`. Don't reason about it as dead code
@@ -230,6 +240,18 @@ vertices, UVs, or indices, call updateVertices(). WebGL keeps Mesh indices
230
240
  separate from quad indices and splits oversized meshes into ordered batches
231
241
  with local index remapping (player/webgl/split-mesh.ts).
232
242
 
243
+ ## Text alignment in 2.5.0
244
+
245
+ `TextLineLayout.ts` caches alphabetic `baseline` and visible `inkAscent` /
246
+ `inkDescent` per line. `TextVerticalLayout.ts` centers ink only for dynamic,
247
+ single-line middle alignment. Multiline/INPUT/top/bottom retain nominal rows
248
+ with content-independent font frames, including blank lines. Canvas, WebGL
249
+ rasterization and link hit testing share the offset. Render bounds add glyph
250
+ margin without changing measurement, input or external clip boundaries. See
251
+ [text layout](text-layout.md#visual-centering-and-stable-baselines-core-250).
252
+ Core 2.4.0 on npm does not include this correction; existing consumer peer ranges
253
+ accept 2.5.0 without SDK bumps. Adoption updates the Core installation/lock.
254
+
233
255
  ## Text layout in 2.0.1
234
256
 
235
257
  Word-wrapped text uses Unicode 17.0 UAX #14, dictionary tailoring for SA scripts
@@ -1,6 +1,6 @@
1
1
  # @kurot/core architecture
2
2
 
3
- > Package version: 2.2.1. See [CHANGELOG.md](../CHANGELOG.md) for release notes.
3
+ > Package version: 2.5.0 (pending publication; latest verified npm release: 2.4.0). See [CHANGELOG.md](../CHANGELOG.md) for release notes.
4
4
  > The [AI context map](./ai-context.md) covers directories, non-obvious behavior,
5
5
  > terminology and task-to-file references. This document explains design choices
6
6
  > and internal mechanisms for contributors; the two documents complement each other.
@@ -18,6 +18,13 @@ Since 2.2.0, Core uses published `@kurot/bitmap-font ^0.1.0` as the headless fon
18
18
  and layout kernel. Core manages font resources, image-page ownership and glyph
19
19
  drawing in both backends. UI components belong to the UI package.
20
20
 
21
+ Since 2.4.0, `DisplayObject.flipX`/`flipY` reflect around a local frame center
22
+ independently of authored scale and anchors. `matrix` exposes the authored
23
+ transform; `$getMatrix()` supplies the effective reflection transform to
24
+ rendering and coordinate conversion. UI provides its validated layout frame
25
+ through `$getFlipBounds()`. See [centered flips](centered-flips.md) for frame,
26
+ scrolling, caching and consumer requirements.
27
+
21
28
  TextField uses Unicode 17.0 line-break rules with dictionary and overflow
22
29
  tailoring. Since 2.2.1, tailoring uses imported rule identities, and layout
23
30
  filters optional break positions through `Intl.Segmenter` grapheme boundaries.
@@ -35,9 +35,15 @@ invalid periods, fractional dimensions and nine-slice precedence. The minified
35
35
  native Canvas patterns on Canvas/WebGL 1/WebGL 2 at 1x/2x, including rotation,
36
36
  tint, cache updates and the existing scale path.
37
37
 
38
- There are no new APIs or dependencies. Existing UI, Game, DragonBones, Spine and
39
- ui-runtime Core peers accept this patch. Their SDK versions and minimum ranges
40
- do not change; optional development lock adoption is separate. Editor's local
38
+ The Core 2.5.0 [texture density extension](texture-density.md) additionally
39
+ tests source densities 1×/2×/3× at both output resolutions. Physical atlas sampling
40
+ and logical repeat periods remain separate, including tinted cached images and
41
+ nine-slice texture swaps. Published 2.4.0 does not interpret sheet density metadata.
42
+
43
+ There are no new APIs or dependencies. UI 3.3.0/runtime 0.9.0 and
44
+ Game/DragonBones/Spine peers accept this patch without SDK bumps. Current
45
+ UI 3.4.0/runtime 0.10.0 require Core ^2.4.0 for centered flips; that release
46
+ includes the fill correction. Optional development lock adoption is separate. Editor's local
41
47
  0.23.1 trial bound one built Core through `KUROT_CORE_PATH` while retaining its
42
48
  published 2.3.2 dependency lock. Editor 0.23.2 adopts registry Core 2.3.3 and
43
49
  updates its Bun lock; ordinary builds no longer require a local engine checkout.
@@ -66,6 +66,8 @@ art. NaN removes a dimension constraint. Height admits complete line boxes;
66
66
  multiline=false draws the first hard-separated line without width wrapping.
67
67
  Explicit zero height draws nothing. Default textureScaleFactor=1 is required for
68
68
  font assets in this initial implementation.
69
+ The Core 2.5.0 texture-density extension keeps literal font metrics separate:
70
+ BitmapFont page textures require resolution=1. See [texture density](texture-density.md).
69
71
 
70
72
  WebGL's BitmapTextPipe submits cropped glyph quads to ordinary texture batching,
71
73
  with current transforms, alpha, tint, blend, clipping and filters. Canvas uses the
@@ -80,6 +82,8 @@ now controls fallback spaces. Line-height, trailing-advance and complete-line
80
82
  clipping follow the shared
81
83
  format contract rather than the old unrendered class's approximate measurements.
82
84
 
83
- The matching UI release provides BitmapLabel for native/programmatic skins;
84
- published UI 3.1.0 does not include it. KUI catalog/CLI adoption is separate;
85
- existing installed compilers do not gain a new tag automatically.
85
+ UI 3.2.0 introduced native BitmapLabel; UI 3.1.0 does not include it. Current
86
+ UI 3.4.0 retains it and requires Core ^2.4.0. Published document 0.13.0, CLI
87
+ 3.5.0 and runtime 0.10.0 support font authoring, compilation and materialization;
88
+ existing installed compilers do not gain a new tag automatically. See
89
+ [BitmapLabel](../../ui/docs/bitmap-label.md) for the feature's introduction versions.
@@ -1,6 +1,6 @@
1
1
  # Centered display flips (Core 2.4.0)
2
2
 
3
- Prepared in source, not published. `flipX` and `flipY` are boolean DisplayObject
3
+ Core 2.4.0 is published, verified on npm on 2026-10-09. `flipX` and `flipY` are boolean DisplayObject
4
4
  properties, defaulting to false and inherited by all display subclasses.
5
5
 
6
6
  ```ts
@@ -29,6 +29,6 @@ no new runtime dependency. UI alone requires a new Core minimum when adopting
29
29
  its frame hook; other SDKs with Core 2.x peers can adopt Core optionally.
30
30
 
31
31
  The repository [adoption contract](../../../docs/centered-flips.md) records
32
- headless/compiler/runtime versions and publication order. Development checks
33
- use temporary local SDK bindings until the new versions exist on the registry;
34
- installed released locks remain the prior baseline until explicit adoption.
32
+ headless/compiler/runtime versions and publication order. UI development now
33
+ installs registry Core 2.4.0 without local overrides. UI 3.4.0 and document
34
+ 0.13.0, CLI 3.5.0 and runtime 0.10.0 are also published. Consumers adopt each installation/lock explicitly and rebuild.
package/docs/resource.md CHANGED
@@ -221,6 +221,11 @@ Load a sprite sheet in TexturePacker JSON format in two steps:
221
221
  1. Load the JSON descriptor to obtain frame data and the image path.
222
222
  2. Load the image and create subtextures.
223
223
 
224
+ The Core 2.5.0 [texture density extension](texture-density.md) accepts optional
225
+ sheet JSON `resolution` (default 1). Frame coordinates and original dimensions
226
+ in JSON remain physical pixels; loaded Texture dimensions and trim offsets are
227
+ logical. Published Core 2.4.0 does not interpret this field.
228
+
224
229
  Resources can be retrieved in three ways:
225
230
 
226
231
  ```typescript
@@ -40,6 +40,47 @@ Dictionary and grapheme segmentation follow the browser's `Intl` data. The
40
40
  pinned Unicode 17.0 tables govern the line-break profile; they do not replace
41
41
  the browser's grapheme implementation.
42
42
 
43
+ ## Visual centering and stable baselines (Core 2.5.0)
44
+
45
+ Canvas and WebGL use the same alphabetic baseline and logical-pixel Canvas
46
+ `TextMetrics`. Each cached line records `baseline`, `inkAscent` and `inkDescent`;
47
+ rich runs share that baseline, even when their sizes or font families differ.
48
+ Visible bounds include fallback glyphs, accents and combining marks. No language
49
+ or operating-system offset table is used.
50
+
51
+ - Dynamic text with `multiline = false` and `verticalAlign = "middle"` centers
52
+ the union of visible run ink in the field. Empty/whitespace-only lines use
53
+ the nominal line box. Changing a button caption may change its baseline so
54
+ its visible glyphs remain centered.
55
+ - Multiline text and INPUT retain font-based baselines. Font-frame bounds are
56
+ measured with an empty string per font configuration, independently of the
57
+ current caption and its fallback glyphs. Empty lines retain the same frame.
58
+ Input caret/selection use the nominal row; composition underlines stay inside
59
+ the viewport. Top/bottom alignment also uses nominal line boxes.
60
+ - `textHeight`, `measureText()`, wrapping, row spacing and layout bounds retain
61
+ their nominal size contract. Dynamic glyph overhang is added only to render
62
+ captures, together with outlines; INPUT and external clips remain exact.
63
+ - Measurements are reused with the TextField line cache. After loading/replacing
64
+ a font, call `invalidateTextMetrics()` through the existing readiness path.
65
+ Fonts and browser rasterization can differ across systems; centering follows
66
+ the actual selected glyphs rather than promising identical pixels.
67
+
68
+ See the [Canvas TextMetrics contract](https://html.spec.whatwg.org/multipage/canvas.html#textmetrics).
69
+ The correction is included in Core 2.5.0, pending publication; it is not in
70
+ published Core 2.4.0. There is no new alignment
71
+ property, runtime dependency or XML format. Default KUI single-line control
72
+ labels use the existing flags with symmetric padding. Adopt Core 2.5.0 after
73
+ publication and rebuild to receive this behavior; SDK peers need no
74
+ incidental change.
75
+
76
+ `test/TextVerticalLayout.test.ts` covers ink centering, mixed sizes, stable input
77
+ and paragraph baselines, link hits, blank rows, overhang and font invalidation.
78
+ The minified `text-alignment.spec.ts` compares 18 multilingual strings in regular
79
+ and bold faces against an independent Canvas reference in Canvas/WebGL 1/2 at
80
+ 1×/2×, including rich runs, outlines, nested caches and tight Thai/Hindi rows.
81
+ The continuous-frame checks also cover restoring the root WebGL target after
82
+ its initial offscreen allocation.
83
+
43
84
  ## Independent measurement (Core 2.3.0)
44
85
 
45
86
  `textField.measureText(width = NaN)` measures complete content under a separate
@@ -0,0 +1,96 @@
1
+ # Texture density
2
+
3
+ This API is included in Core 2.5.0, prepared for publication but not yet
4
+ published. Published Core 2.4.0 and earlier do not interpret sheet `resolution`.
5
+
6
+ `new Texture(resolution)` describes source pixels per logical unit. The default
7
+ is 1; the value must be finite and positive, is immutable, and is inherited by
8
+ SpriteSheet views. Different densities can share one scene and GPU batch.
9
+ Player/ScreenAdapter resolution controls the output canvas independently.
10
+
11
+ ```ts
12
+ const texture = new Texture(2);
13
+ texture.setBitmapData(new BitmapData(image));
14
+ // A 56×56 image has textureWidth/textureHeight of 28×28.
15
+ const icon = new Bitmap(texture);
16
+ ```
17
+
18
+ ## Units
19
+
20
+ | Value | Unit |
21
+ | --- | --- |
22
+ | BitmapData width/height | Physical source pixels |
23
+ | Texture bitmapX/Y and bitmapWidth/Height | Physical atlas sampling pixels |
24
+ | Texture sourceWidth/Height | Physical atlas page pixels used for UV normalization |
25
+ | Texture offsetX/Y and textureWidth/Height | Logical units |
26
+ | Texture scaleBitmapWidth/Height | Logical size of the sampled upright region |
27
+ | Texture pixelScale | Logical units per source pixel, including textureScaleFactor |
28
+ | SpriteSheet.createTexture arguments and sheet frame geometry | Source pixels |
29
+ | Bitmap/Image width/height, scale9Grid and XML layout | Logical units |
30
+
31
+ At the normal textureScaleFactor of 1, logical frame sizes and trim offsets are
32
+ source values divided by resolution. Atlas coordinates and page dimensions are
33
+ never divided for sampling. A grid is relative to the original untrimmed logical
34
+ frame; atlas placement and trimmed physical offsets do not change that frame.
35
+
36
+ ## Sheet resources
37
+
38
+ The density lives in the atlas JSON, beside `file` and `frames`, rather than in
39
+ the resource manifest or XML. Omitting it retains 1× behavior. Invalid values
40
+ fail the sheet load before its image is requested.
41
+
42
+ ```json
43
+ {
44
+ "file": "kui.png",
45
+ "resolution": 2,
46
+ "frames": {
47
+ "button_up": { "x": 8, "y": 8, "w": 96, "h": 96 }
48
+ }
49
+ }
50
+ ```
51
+
52
+ The original frame is 48×48 logical units. Its manifest default remains
53
+ `"scale9grid": "16,16,16,16"`. Images keep their existing XML allocation and
54
+ corner sizes. Crop/trim/sourceW/sourceH in the sheet are physical pixels;
55
+ logical original dimensions are sourceW/resolution and sourceH/resolution.
56
+
57
+ Scale, clip, repeat, tint, nine-slice and Canvas-backed caches use each texture's
58
+ pixelScale. Repeat periods and fixed nine-slice borders stay logical. UVs and
59
+ GPU uploads still address the physical page. Mesh vertices remain authored
60
+ logical geometry; density does not rescale vertices.
61
+
62
+ Standalone ImageAnalyzer resources retain 1×; use an explicitly constructed
63
+ Texture for an independently loaded high-density image. No filename suffix is
64
+ inferred. RenderTexture retains its capture API and does not accept source-density
65
+ constructor arguments. BitmapFont's literal descriptor metrics still require a
66
+ page with resolution=1; this feature does not reinterpret font metrics.
67
+
68
+ ## Adoption and verification
69
+
70
+ The default KUI kit now generates 2× pixels from SVG geometry with two physical
71
+ pixels of extrusion, preserving logical layout, hit targets and grids. It needs
72
+ Core ^2.5.0. Existing 1× resources require no
73
+ migration. UI/Game/DragonBones/Spine/ui-runtime peer ranges accepting Core 2.x
74
+ can use that Core release without an SDK bump. CLI still has no Core dependency.
75
+
76
+ The source trial lives in an isolated directory under docs-internal and binds
77
+ the built checkout Core explicitly; it does not alter registry locks. Read
78
+ [default KUI skins](../../cli/docs/default-ui-skins.md) for the preview command.
79
+ Publish Core 2.5.0 before CLI 3.6.0 so new scaffolds resolve the required Core.
80
+ Editor/Reskin resource authoring tools must adopt the new Core and divide physical
81
+ frame dimensions by sheet resolution when validating logical grids or measuring
82
+ previews; their current released installations do not understand this metadata.
83
+
84
+ Unit regressions cover mixed densities, nested trimmed views, atlas loading,
85
+ fixed borders, trim, clip/repeat and rotated edge crops. The minified browser
86
+ fill tests compare Canvas/WebGL 1/WebGL 2 pixels at output resolution 1×/2×
87
+ with source density 1×/2×/3×, including tint, texture swaps, cache updates and
88
+ nine-slice invariance.
89
+
90
+ Source verification on 2026-10-10: Core implementation/declaration builds and
91
+ 890 unit tests pass; CLI's 112 tests pass. All six minified pixel cases pass
92
+ across the three backends and two output resolutions. The isolated native KUI
93
+ gallery passes dev/release checks in all three backends at render resolution 2:
94
+ 640×1136 logical stage/CSS, 1280×2272 backing pixels, 48×48 logical button frames
95
+ from 96×96 source regions, 28×28 logical icons from 56×56 source regions, unchanged
96
+ 16,16,16,16 grids, pressed-state restoration and correctly mapped button taps.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurot/core",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "Modern rewrite of the Egret game engine — WebGL multi-texture batching, instruction-driven render pipeline, strict TypeScript, Egret-compatible API",
5
5
  "author": "Kelvin <kyia.x52@gmail.com>",
6
6
  "license": "MIT",