@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
package/CHANGELOG.md CHANGED
@@ -4,16 +4,75 @@ All notable changes to `@kurot/core` are documented here.
4
4
 
5
5
  ---
6
6
 
7
+ ## [2.5.0] — 2026-10-10
8
+
9
+ Prepared for publication; not yet published. Latest verified npm release is
10
+ 2.4.0. Publish Core 2.5.0 before CLI 3.6.0, whose game template uses 2× sheets.
11
+
12
+ ### Added
13
+
14
+ - Independent immutable `Texture.resolution`, inherited by SpriteSheet views,
15
+ and optional sheet JSON `resolution`. Sampling/UV coordinates remain physical
16
+ while original dimensions, trim offsets, repeat periods and nine-slice borders
17
+ remain logical. Bitmap/Image scale, clip, repeat, tint and Canvas-backed caches
18
+ support mixed source densities in Canvas and WebGL. Existing sheets default
19
+ to 1×; malformed densities fail loading. See [texture density](docs/texture-density.md).
20
+
21
+ ### Fixed
22
+
23
+ - Preserve ItemRenderer and other bitmap edges at fractional WebGL viewport
24
+ scales/translations. Axis-aligned clips enclose transformed physical bounds
25
+ before calculating scissor dimensions, retaining partially covered edge pixels.
26
+ Integer boundaries and nested/rotated stencil clips keep their existing behavior.
27
+ - Center single-line dynamic middle-aligned text by measured ink bounds across
28
+ languages. Share alphabetic baselines between rich runs; retain stable font
29
+ frames for paragraphs, empty lines and inputs. Keep layout/measurement sizes
30
+ nominal, preserve glyph overhang in dynamic captures, and align link hits,
31
+ selection, caret and composition decoration with the same row geometry.
32
+ - Restore the root WebGL render target after the first scratch-buffer allocation
33
+ by cycling a real 1×1 target, preventing the second frame from retaining old
34
+ pixels while drawing into the scratch framebuffer.
35
+
36
+ ### Compatibility
37
+
38
+ - Compatible API addition; existing 1× resources and public text flags retain
39
+ their contracts. No new runtime dependencies or resource-manifest/KUI fields.
40
+ - UI, Game, DragonBones, Spine and ui-runtime Core peers already accept 2.5.0.
41
+ Their package versions, peer minima and development locks need no incidental
42
+ change. Applications adopt this Core installation/lock and rebuild explicitly.
43
+ - Projects using the CLI 3.6.0 default 2× skin kit require Core >=2.5.0 within
44
+ the 2.x line. Editor/Reskin adoption additionally needs logical frame dimensions
45
+ derived from source density; their current installations remain unchanged.
46
+
47
+ ### Verification — 2026-10-10
48
+
49
+ - Core build and 890 unit tests; CLI build and 112 unit tests pass.
50
+ - Package dry-run verifies the 2.5.0 manifest, implementation/declarations,
51
+ density/text documentation and release notes.
52
+ - 12 minified text alignment/outline browser checks pass in Canvas, WebGL 1/2
53
+ at 1×/2×. Six golden/context-restoration/high-density checks and 30 filter
54
+ checks pass. Reviewed golden changes include the shared text baseline and
55
+ the correctly rendered blurred surface after root-target restoration.
56
+ - Four fractional-viewport pixel regressions pass in WebGL 1/2 at 1×/2×,
57
+ including reflection and scrolling. All 24 related nested-clip, outline and
58
+ filter-chain checks pass after scissor quantization.
59
+ - Isolated native KUI example passes strict development and release builds;
60
+ the local 2× preview retains stable English/Thai/Chinese input baselines and
61
+ the intended 2-pixel pressed caption offset. Windows is not tested.
62
+
7
63
  ## [2.4.0] — 2026-10-09
8
64
 
9
- Prepared in source; not published.
65
+ Published; verified on npm on 2026-10-09. Existing Core 2.x peer ranges
66
+ accept this optional API addition. UI 3.4.0 adopts the reflection-frame hook
67
+ and requires Core ^2.4.0.
10
68
 
11
69
  ### Added
12
70
 
13
71
  Added independent false-default flipX/flipY on DisplayObject, reflecting around the local content or scroll viewport center while preserving authored scale, position and anchors. Both backends and coordinate/hit-test paths share the effective transform; reflected ancestor bounds changes refresh descendant transforms.
14
72
 
15
73
  See [centered flips](../../docs/centered-flips.md) for semantics, adoption and
16
- temporary verification bindings. Registry lock refresh follows upstream publication.
74
+ consumer verification. UI development now installs published Core 2.4.0 with
75
+ a matching registry lockfile; no local Core override is needed.
17
76
 
18
77
  ### Verification
19
78
 
package/README.md CHANGED
@@ -1,11 +1,23 @@
1
1
  # @kurot/core
2
2
 
3
- Source prepares **2.4.0**, not published. See [centered flips](docs/centered-flips.md)
4
- for the new APIs, exact requirements and publication/lockfile order.
3
+ **2.5.0 is prepared for publication, not yet published.** Latest verified npm
4
+ release: 2.4.0. This release adds independent source texture density and fixes
5
+ text alignment, fractional viewport edges and root WebGL target restoration.
6
+ See [texture density](docs/texture-density.md) and [CHANGELOG.md](CHANGELOG.md).
5
7
 
6
8
  A modern rewrite of the Egret game engine. Maintains Egret-compatible display object and event APIs while upgrading the rendering architecture, type safety, and tooling.
7
9
 
8
- > **Package version: 2.4.0 (unpublished).** Targets ES2022 and evergreen browsers (Chrome / Edge / Firefox / Safari). No IE / old-Android / pre-2022 Safari support shims.
10
+ > **Package version: 2.5.0 (pending publication).** Targets ES2022 and evergreen browsers (Chrome / Edge / Firefox / Safari). No IE / old-Android / pre-2022 Safari support shims.
11
+
12
+ ## Text alignment correction in 2.5.0
13
+
14
+ Single-line dynamic middle alignment centers measured glyph ink, including
15
+ fallback fonts and accents. Multiline text and input keep stable font baselines;
16
+ rich runs share an alphabetic baseline. Layout sizes and wrapping stay nominal.
17
+ The existing font-readiness invalidation refreshes these cached metrics.
18
+ See [text alignment](docs/text-layout.md#visual-centering-and-stable-baselines-core-250).
19
+ Install Core 2.5.0 after publication and rebuild to adopt it; published 2.4.0
20
+ does not include the correction. Existing SDK peer ranges require no change.
9
21
 
10
22
  ## Bitmap fill correction in 2.3.3
11
23
 
@@ -13,8 +25,9 @@ A modern rewrite of the Egret game engine. Maintains Egret-compatible display ob
13
25
  backends and bitmap caches. Repeat uses the original texture dimensions, including
14
26
  transparent trim margins; partial edge tiles are cropped rather than stretched.
15
27
  Nine-slice remains active only for `scale`. No XML or resource migration is needed.
16
- Core 2.3.3 is published; Core 2.3.2 does not include this fix. Existing
17
- Core 2.x peers accept the patch without another SDK release. Applications adopt
28
+ Core 2.3.3 is published; Core 2.3.2 does not include this fix. UI 3.3.0/runtime
29
+ 0.9.0 and Game/DragonBones/Spine peers accept it without SDK bumps. Current
30
+ UI 3.4.0/runtime 0.10.0 require Core ^2.4.0, which includes it. Applications adopt
18
31
  its installation/lock and rebuild; templates are not rewritten.
19
32
  See [bitmap fill modes](docs/bitmap-fill.md).
20
33
 
@@ -25,8 +38,9 @@ Canvas drawing, WebGL text textures, display-list caches, filter captures and
25
38
  object-mask buffers. Rich-text run strokes are included. Layout measurements,
26
39
  wrapping and alignment retain their existing dimensions; input viewports and
27
40
  external clips remain exact. This fix is not included in published 2.3.1.
28
- No API or resource-format migration is required. Existing UI, Game, DragonBones,
29
- Spine and ui-runtime Core peers accept this patch without another SDK release.
41
+ No API or resource-format migration is required. UI 3.3.0/runtime 0.9.0 and
42
+ Game/DragonBones/Spine peers accept the patch without SDK bumps. Current
43
+ UI 3.4.0/runtime 0.10.0 require Core ^2.4.0, which includes it.
30
44
  Update the application's installation and lockfile, then rebuild; existing
31
45
  bundled Editor Apps retain their old Core until rebuilt.
32
46
  See [text layout](docs/text-layout.md#text-outlines-core-232).
@@ -35,8 +49,9 @@ See [text layout](docs/text-layout.md#text-outlines-core-232).
35
49
 
36
50
  An unstyled blank run between styled runs now uses the TextField base font size,
37
51
  matching other unstyled content, rather than borrowing a later run's size.
38
- Core 2.3.1 is published as a compatible patch. Existing Core 2.x
39
- peers accept it without dependent SDK version bumps.
52
+ Core 2.3.1 is published as a compatible patch. Consumers whose Core peer range
53
+ accepts it need no SDK bump. Current UI 3.4.0/runtime 0.10.0 require Core ^2.4.0,
54
+ which includes the correction.
40
55
 
41
56
  ## Independent text measurement in 2.3.0
42
57
 
@@ -69,6 +84,15 @@ The existing UI 3.2.0, Game 2.0.0, ui-runtime 0.8.2 and DragonBones 0.1.0 peer
69
84
  ranges accept it. Update the installed Core version and lockfile to receive
70
85
  the fixes; see [text layout](docs/text-layout.md).
71
86
 
87
+ ## Fractional viewport clipping in 2.5.0
88
+
89
+ Axis-aligned WebGL clips now floor their left/top physical edges and ceil their
90
+ right/bottom edges before calculating scissor dimensions. This preserves boundary
91
+ pixels when a scaled UI list or another viewport lands between pixels, avoiding
92
+ cut-off nine-slice outlines. Scissor precision remains one physical pixel; nested
93
+ or rotated clips retain the stencil path. No skin padding or layout change is
94
+ required. Published Core 2.4.0 does not include this correction.
95
+
72
96
  ## Scroll clipping in 2.1.1
73
97
 
74
98
  WebGL keeps a `scrollRect` viewport fixed when it is nested inside another clip
@@ -99,7 +123,8 @@ matching UI release; Core does not expose `textFit` or `minFontSize`.
99
123
  ## Installation
100
124
 
101
125
  ```bash
102
- pnpm add @kurot/core@^2.3.3
126
+ # After Core 2.5.0 is published:
127
+ pnpm add @kurot/core@^2.5.0
103
128
  ```
104
129
 
105
130
  Core depends on `@kurot/bitmap-font ^0.1.0` for bitmap-font data and shared
@@ -263,6 +288,11 @@ text and `cacheAsTexture(true)` caches will be regenerated at the new density.
263
288
  WebGL vector graphics are also re-rasterized when their display scale increases;
264
289
  their cached sampling scale is capped at 8× to bound zoom-related memory use.
265
290
 
291
+ The Core 2.5.0 [texture density API](docs/texture-density.md) adds independent
292
+ source density through `new Texture(2)` and sheet JSON `resolution: 2`.
293
+ High-density images retain logical dimensions and nine-slice corners while
294
+ sampling physical atlas pixels. Published Core 2.4.0 does not contain this API.
295
+
266
296
  ## Multilingual text
267
297
 
268
298
  `TextField.wordWrap = true` uses Unicode 17.0 UAX #14, with dictionary
@@ -384,8 +414,8 @@ to arbitrary `Bitmap` objects. See the
384
414
  [resource format](docs/resource.md) and
385
415
  [nine-slice contract](../ui-document/docs/resource-nine-slice.md).
386
416
 
387
- The optional `resource/config/style.json` is handled by published ui-document 0.11.0 and
388
- CLI 3.3.0, including named colors and Label presets. Core does not read this file or interpret `@style:colors:<key>` XML
417
+ The optional `resource/config/style.json` is handled by current document 0.13.0 and
418
+ CLI 3.5.0, including named colors and Label presets. Core does not read this file or interpret `@style:colors:<key>` XML
389
419
  references. Compiled skins receive numeric RGB values; the application loads
390
420
  fonts before measuring text. See the
391
421
  [project style contract](../ui-document/docs/project-styles.md).
@@ -402,5 +432,6 @@ Widths/heights are layout constraints; use scaleX/scaleY to resize the artwork.
402
432
  Height admits complete lines, and explicit `multiline = false` keeps the first
403
433
  hard-separated line unwrapped. `BitmapText.EMPTY_FACTOR` is deprecated in favor
404
434
  of `font.data.spaceAdvance`. See the linked contracts before migrating custom
405
- bitmap-text measurements. KUI tags and Editor materialization need separate
406
- consumer releases.
435
+ bitmap-text measurements. Native UI BitmapLabel was introduced in UI 3.2.0;
436
+ current UI 3.4.0, document 0.13.0, CLI 3.5.0 and runtime 0.10.0 include its native,
437
+ authoring, compilation and materialization contracts. Editor adoption is separate.
@@ -6,6 +6,7 @@ export declare class RenderTexture extends Texture {
6
6
  static renderer?: RenderFunction;
7
7
  private _canvas?;
8
8
  private _ctx?;
9
+ constructor();
9
10
  drawToTexture(displayObject: DisplayObject, clipBounds?: Rectangle, scale?: number): boolean;
10
11
  getPixel32(x: number, y: number): number[];
11
12
  dispose(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"RenderTexture.d.ts","sourceRoot":"","sources":["../../../../src/kurot/display/texture/RenderTexture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAE,OAAO,EAAsB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,KAAK,cAAc,GAAG,CACrB,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,KACX,iBAAiB,CAAC;AAEvB,qBAAa,aAAc,SAAQ,OAAO;IAGzC,MAAM,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAIjC,OAAO,CAAC,OAAO,CAAC,CAAoB;IACpC,OAAO,CAAC,IAAI,CAAC,CAA2B;IAIjC,aAAa,CAAC,aAAa,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,SAAS,EAAE,KAAK,SAAI,GAAG,OAAO;IA+B9E,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAa1C,OAAO,IAAI,IAAI;CAK/B"}
1
+ {"version":3,"file":"RenderTexture.d.ts","sourceRoot":"","sources":["../../../../src/kurot/display/texture/RenderTexture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAE,OAAO,EAAsB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,KAAK,cAAc,GAAG,CACrB,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,KACX,iBAAiB,CAAC;AAEvB,qBAAa,aAAc,SAAQ,OAAO;IAGzC,MAAM,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAIjC,OAAO,CAAC,OAAO,CAAC,CAAoB;IACpC,OAAO,CAAC,IAAI,CAAC,CAA2B;;IAUjC,aAAa,CAAC,aAAa,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,SAAS,EAAE,KAAK,SAAI,GAAG,OAAO;IA+B9E,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAa1C,OAAO,IAAI,IAAI;CAK/B"}
@@ -6,6 +6,10 @@ export class RenderTexture extends Texture {
6
6
  // ── Instance fields ───────────────────────────────────────────────────────
7
7
  _canvas;
8
8
  _ctx;
9
+ // ── Constructor ───────────────────────────────────────────────────────────
10
+ constructor() {
11
+ super();
12
+ }
9
13
  // ── Public methods ────────────────────────────────────────────────────────
10
14
  drawToTexture(displayObject, clipBounds, scale = 1) {
11
15
  if (clipBounds && (clipBounds.width === 0 || clipBounds.height === 0)) {
@@ -1 +1 @@
1
- {"version":3,"file":"RenderTexture.js","sourceRoot":"","sources":["../../../../src/kurot/display/texture/RenderTexture.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RenderTexture.js","sourceRoot":"","sources":["../../../../src/kurot/display/texture/RenderTexture.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,10 @@ export declare class SpriteSheet {
6
6
  private _textureMap;
7
7
  constructor(texture: Texture);
8
8
  getTexture(name: string): Texture | undefined;
9
+ /**
10
+ * Creates a view using source-pixel coordinates, trim offsets and original
11
+ * frame dimensions. Logical dimensions inherit the page's resolution.
12
+ */
9
13
  createTexture(name: string, bitmapX: number, bitmapY: number, bitmapWidth: number, bitmapHeight: number, offsetX?: number, offsetY?: number, textureWidth?: number, textureHeight?: number): Texture;
10
14
  dispose(): void;
11
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SpriteSheet.d.ts","sourceRoot":"","sources":["../../../../src/kurot/display/texture/SpriteSheet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,qBAAa,WAAW;IAGvB,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAA8B;gBAI9B,OAAO,EAAE,OAAO;IAQ5B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI7C,aAAa,CACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,SAAI,EACX,OAAO,SAAI,EACX,YAAY,CAAC,EAAE,MAAM,EACrB,aAAa,CAAC,EAAE,MAAM,GACpB,OAAO;IAsBH,OAAO,IAAI,IAAI;CAGtB"}
1
+ {"version":3,"file":"SpriteSheet.d.ts","sourceRoot":"","sources":["../../../../src/kurot/display/texture/SpriteSheet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,qBAAa,WAAW;IAGvB,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAA8B;gBAI9B,OAAO,EAAE,OAAO;IAQ5B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAIpD;;;OAGG;IACI,aAAa,CACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,SAAI,EACX,OAAO,SAAI,EACX,YAAY,CAAC,EAAE,MAAM,EACrB,aAAa,CAAC,EAAE,MAAM,GACpB,OAAO;IAsBH,OAAO,IAAI,IAAI;CAGtB"}
@@ -8,17 +8,21 @@ export class SpriteSheet {
8
8
  // ── Constructor ───────────────────────────────────────────────────────────
9
9
  constructor(texture) {
10
10
  this._texture = texture;
11
- this._bitmapX = texture.bitmapX - texture.offsetX;
12
- this._bitmapY = texture.bitmapY - texture.offsetY;
11
+ this._bitmapX = texture.bitmapX - texture.offsetX / texture.pixelScale;
12
+ this._bitmapY = texture.bitmapY - texture.offsetY / texture.pixelScale;
13
13
  }
14
14
  // ── Public methods ────────────────────────────────────────────────────────
15
15
  getTexture(name) {
16
16
  return this._textureMap.get(name);
17
17
  }
18
+ /**
19
+ * Creates a view using source-pixel coordinates, trim offsets and original
20
+ * frame dimensions. Logical dimensions inherit the page's resolution.
21
+ */
18
22
  createTexture(name, bitmapX, bitmapY, bitmapWidth, bitmapHeight, offsetX = 0, offsetY = 0, textureWidth, textureHeight) {
19
23
  const tw = textureWidth ?? offsetX + bitmapWidth;
20
24
  const th = textureHeight ?? offsetY + bitmapHeight;
21
- const texture = new Texture();
25
+ const texture = new Texture(this._texture.resolution);
22
26
  texture.disposeBitmapData = false;
23
27
  texture.bitmapData = this._texture.bitmapData;
24
28
  texture.initData(this._bitmapX + bitmapX, this._bitmapY + bitmapY, bitmapWidth, bitmapHeight, offsetX, offsetY, tw, th, this._texture.sourceWidth, this._texture.sourceHeight);
@@ -1 +1 @@
1
- {"version":3,"file":"SpriteSheet.js","sourceRoot":"","sources":["../../../../src/kurot/display/texture/SpriteSheet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,OAAO,WAAW;IACvB,6EAA6E;IAErE,QAAQ,CAAU;IAClB,QAAQ,CAAS;IACjB,QAAQ,CAAS;IACjB,WAAW,GAAG,IAAI,GAAG,EAAmB,CAAC;IAEjD,6EAA6E;IAE7E,YAAmB,OAAgB;QAClC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAClD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACnD,CAAC;IAED,6EAA6E;IAEtE,UAAU,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAEM,aAAa,CACnB,IAAY,EACZ,OAAe,EACf,OAAe,EACf,WAAmB,EACnB,YAAoB,EACpB,OAAO,GAAG,CAAC,EACX,OAAO,GAAG,CAAC,EACX,YAAqB,EACrB,aAAsB;QAEtB,MAAM,EAAE,GAAG,YAAY,IAAI,OAAO,GAAG,WAAW,CAAC;QACjD,MAAM,EAAE,GAAG,aAAa,IAAI,OAAO,GAAG,YAAY,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAC9B,OAAO,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAClC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC9C,OAAO,CAAC,QAAQ,CACf,IAAI,CAAC,QAAQ,GAAG,OAAO,EACvB,IAAI,CAAC,QAAQ,GAAG,OAAO,EACvB,WAAW,EACX,YAAY,EACZ,OAAO,EACP,OAAO,EACP,EAAE,EACF,EAAE,EACF,IAAI,CAAC,QAAQ,CAAC,WAAW,EACzB,IAAI,CAAC,QAAQ,CAAC,YAAY,CAC1B,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,OAAO,OAAO,CAAC;IAChB,CAAC;IAEM,OAAO;QACb,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;CACD"}
1
+ {"version":3,"file":"SpriteSheet.js","sourceRoot":"","sources":["../../../../src/kurot/display/texture/SpriteSheet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,OAAO,WAAW;IACvB,6EAA6E;IAErE,QAAQ,CAAU;IAClB,QAAQ,CAAS;IACjB,QAAQ,CAAS;IACjB,WAAW,GAAG,IAAI,GAAG,EAAmB,CAAC;IAEjD,6EAA6E;IAE7E,YAAmB,OAAgB;QAClC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;QACvE,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IACxE,CAAC;IAED,6EAA6E;IAEtE,UAAU,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED;;;OAGG;IACI,aAAa,CACnB,IAAY,EACZ,OAAe,EACf,OAAe,EACf,WAAmB,EACnB,YAAoB,EACpB,OAAO,GAAG,CAAC,EACX,OAAO,GAAG,CAAC,EACX,YAAqB,EACrB,aAAsB;QAEtB,MAAM,EAAE,GAAG,YAAY,IAAI,OAAO,GAAG,WAAW,CAAC;QACjD,MAAM,EAAE,GAAG,aAAa,IAAI,OAAO,GAAG,YAAY,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACtD,OAAO,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAClC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC9C,OAAO,CAAC,QAAQ,CACf,IAAI,CAAC,QAAQ,GAAG,OAAO,EACvB,IAAI,CAAC,QAAQ,GAAG,OAAO,EACvB,WAAW,EACX,YAAY,EACZ,OAAO,EACP,OAAO,EACP,EAAE,EACF,EAAE,EACF,IAAI,CAAC,QAAQ,CAAC,WAAW,EACzB,IAAI,CAAC,QAAQ,CAAC,YAAY,CAC1B,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,OAAO,OAAO,CAAC;IAChB,CAAC;IAEM,OAAO;QACb,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;CACD"}
@@ -2,6 +2,11 @@ import { Rectangle } from '../../geom/Rectangle.js';
2
2
  import { BitmapData } from './BitmapData.js';
3
3
  export declare let textureScaleFactor: number;
4
4
  export declare class Texture {
5
+ /**
6
+ * Source pixels per logical unit. Immutable for this texture and inherited
7
+ * by SpriteSheet views; independent of the player's render resolution.
8
+ */
9
+ readonly resolution: number;
5
10
  bitmapX: number;
6
11
  bitmapY: number;
7
12
  bitmapWidth: number;
@@ -15,6 +20,11 @@ export declare class Texture {
15
20
  disposeBitmapData: boolean;
16
21
  private _textureWidth;
17
22
  private _textureHeight;
23
+ constructor(resolution?: number);
24
+ /**
25
+ * Logical units per sampled source pixel, including textureScaleFactor.
26
+ */
27
+ get pixelScale(): number;
18
28
  get textureWidth(): number;
19
29
  get textureHeight(): number;
20
30
  get scaleBitmapWidth(): number;
@@ -33,6 +43,10 @@ export declare class Texture {
33
43
  * @deprecated This operation is not supported by Texture.
34
44
  */
35
45
  toDataURL(_type: string, _rect?: Rectangle): string;
46
+ /**
47
+ * Atlas geometry and original frame sizes are in source pixels. Stored
48
+ * offsets and texture dimensions are logical; page dimensions stay physical.
49
+ */
36
50
  initData(bitmapX: number, bitmapY: number, bitmapWidth: number, bitmapHeight: number, offsetX: number, offsetY: number, textureWidth: number, textureHeight: number, sourceWidth: number, sourceHeight: number, rotated?: boolean): void;
37
51
  }
38
52
  //# sourceMappingURL=Texture.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Texture.d.ts","sourceRoot":"","sources":["../../../../src/kurot/display/texture/Texture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,eAAO,IAAI,kBAAkB,QAAI,CAAC;AAElC,qBAAa,OAAO;IAGnB,OAAO,SAAK;IACZ,OAAO,SAAK;IACZ,WAAW,SAAK;IAChB,YAAY,SAAK;IACjB,OAAO,SAAK;IACZ,OAAO,SAAK;IACZ,WAAW,SAAK;IAChB,YAAY,SAAK;IACjB,OAAO,UAAS;IAChB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,iBAAiB,UAAQ;IAEzB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,cAAc,CAAK;IAI3B,IAAW,YAAY,IAAI,MAAM,CAEhC;IACD,IAAW,aAAa,IAAI,MAAM,CAEjC;IAED,IAAW,gBAAgB,IAAI,MAAM,CAEpC;IACD,IAAW,iBAAiB,IAAI,MAAM,CAErC;IAIM,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAQtC,OAAO,IAAI,IAAI;IAStB;;OAEG;IACI,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE;IAInD;;OAEG;IACI,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,SAAI,EAAE,OAAO,SAAI,GAAG,MAAM,EAAE;IAI3E;;OAEG;IACI,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM;IAM1D,QAAQ,CACP,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,UAAQ,GACb,IAAI;CAeP"}
1
+ {"version":3,"file":"Texture.d.ts","sourceRoot":"","sources":["../../../../src/kurot/display/texture/Texture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,eAAO,IAAI,kBAAkB,QAAI,CAAC;AAElC,qBAAa,OAAO;IAGnB;;;OAGG;IACH,SAAgB,UAAU,EAAE,MAAM,CAAC;IAEnC,OAAO,SAAK;IACZ,OAAO,SAAK;IACZ,WAAW,SAAK;IAChB,YAAY,SAAK;IACjB,OAAO,SAAK;IACZ,OAAO,SAAK;IACZ,WAAW,SAAK;IAChB,YAAY,SAAK;IACjB,OAAO,UAAS;IAChB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,iBAAiB,UAAQ;IAEzB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,cAAc,CAAK;gBAIR,UAAU,SAAI;IASjC;;OAEG;IACH,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED,IAAW,YAAY,IAAI,MAAM,CAEhC;IACD,IAAW,aAAa,IAAI,MAAM,CAEjC;IAED,IAAW,gBAAgB,IAAI,MAAM,CAEpC;IACD,IAAW,iBAAiB,IAAI,MAAM,CAErC;IAIM,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAQtC,OAAO,IAAI,IAAI;IAStB;;OAEG;IACI,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE;IAInD;;OAEG;IACI,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,SAAI,EAAE,OAAO,SAAI,GAAG,MAAM,EAAE;IAI3E;;OAEG;IACI,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM;IAM1D;;;OAGG;IACH,QAAQ,CACP,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,UAAQ,GACb,IAAI;CAeP"}
@@ -2,6 +2,11 @@ import { BitmapData } from './BitmapData.js';
2
2
  export let textureScaleFactor = 1;
3
3
  export class Texture {
4
4
  // ── Instance fields ───────────────────────────────────────────────────────
5
+ /**
6
+ * Source pixels per logical unit. Immutable for this texture and inherited
7
+ * by SpriteSheet views; independent of the player's render resolution.
8
+ */
9
+ resolution;
5
10
  bitmapX = 0;
6
11
  bitmapY = 0;
7
12
  bitmapWidth = 0;
@@ -15,7 +20,20 @@ export class Texture {
15
20
  disposeBitmapData = true;
16
21
  _textureWidth = 0;
17
22
  _textureHeight = 0;
23
+ // ── Constructor ───────────────────────────────────────────────────────────
24
+ constructor(resolution = 1) {
25
+ if (!Number.isFinite(resolution) || resolution <= 0) {
26
+ throw new RangeError('Texture resolution must be a finite positive number.');
27
+ }
28
+ this.resolution = resolution;
29
+ }
18
30
  // ── Getters / Setters ─────────────────────────────────────────────────────
31
+ /**
32
+ * Logical units per sampled source pixel, including textureScaleFactor.
33
+ */
34
+ get pixelScale() {
35
+ return textureScaleFactor / this.resolution;
36
+ }
19
37
  get textureWidth() {
20
38
  return this._textureWidth;
21
39
  }
@@ -23,10 +41,10 @@ export class Texture {
23
41
  return this._textureHeight;
24
42
  }
25
43
  get scaleBitmapWidth() {
26
- return this.bitmapWidth * textureScaleFactor;
44
+ return this.bitmapWidth * this.pixelScale;
27
45
  }
28
46
  get scaleBitmapHeight() {
29
- return this.bitmapHeight * textureScaleFactor;
47
+ return this.bitmapHeight * this.pixelScale;
30
48
  }
31
49
  // ── Public methods ────────────────────────────────────────────────────────
32
50
  setBitmapData(value) {
@@ -63,16 +81,20 @@ export class Texture {
63
81
  throw new Error('toDataURL requires renderer implementation');
64
82
  }
65
83
  // ── Internal methods ──────────────────────────────────────────────────────
84
+ /**
85
+ * Atlas geometry and original frame sizes are in source pixels. Stored
86
+ * offsets and texture dimensions are logical; page dimensions stay physical.
87
+ */
66
88
  initData(bitmapX, bitmapY, bitmapWidth, bitmapHeight, offsetX, offsetY, textureWidth, textureHeight, sourceWidth, sourceHeight, rotated = false) {
67
89
  const scale = textureScaleFactor;
68
90
  this.bitmapX = bitmapX / scale;
69
91
  this.bitmapY = bitmapY / scale;
70
92
  this.bitmapWidth = bitmapWidth / scale;
71
93
  this.bitmapHeight = bitmapHeight / scale;
72
- this.offsetX = offsetX;
73
- this.offsetY = offsetY;
74
- this._textureWidth = textureWidth;
75
- this._textureHeight = textureHeight;
94
+ this.offsetX = offsetX / this.resolution;
95
+ this.offsetY = offsetY / this.resolution;
96
+ this._textureWidth = textureWidth / this.resolution;
97
+ this._textureHeight = textureHeight / this.resolution;
76
98
  this.sourceWidth = sourceWidth;
77
99
  this.sourceHeight = sourceHeight;
78
100
  this.rotated = rotated;
@@ -1 +1 @@
1
- {"version":3,"file":"Texture.js","sourceRoot":"","sources":["../../../../src/kurot/display/texture/Texture.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Texture.js","sourceRoot":"","sources":["../../../../src/kurot/display/texture/Texture.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ import { textureScaleFactor } from '../display/texture/Texture.js';
8
8
  export function drawUnscaledBitmapFill(bitmap, width, height, draw) {
9
9
  const tileWidth = bitmap.textureWidth;
10
10
  const tileHeight = bitmap.textureHeight;
11
- const scale = textureScaleFactor;
11
+ const scale = bitmap.texture?.pixelScale ?? textureScaleFactor;
12
12
  if (![width, height, tileWidth, tileHeight, scale].every(value => Number.isFinite(value) && value > 0)) {
13
13
  return;
14
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bitmap-fill.js","sourceRoot":"","sources":["../../../src/kurot/player/bitmap-fill.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bitmap-fill.js","sourceRoot":"","sources":["../../../src/kurot/player/bitmap-fill.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CanvasRenderer.d.ts","sourceRoot":"","sources":["../../../../src/kurot/player/canvas/CanvasRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAgC,MAAM,gCAAgC,CAAC;AAC7F,OAAO,EAAE,MAAM,EAAyB,MAAM,yBAAyB,CAAC;AAKxE,OAAO,EAAE,QAAQ,EAAsB,MAAM,2BAA2B,CAAC;AAGzE,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAO9C,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAMpD,OAAO,EAAE,YAAY,EAAiB,MAAM,mBAAmB,CAAC;AAwBhE;;GAEG;AACH,qBAAa,cAAc;IAE1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4C;IAC7E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA8C;IACjF,OAAO,CAAC,WAAW,CAAY;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkC;IACpE,OAAO,CAAC,WAAW,CAAK;IAIxB;;OAEG;IACI,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IAiBnF,eAAe,CACrB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,UAAU,SAAI,GACZ,IAAI;IAUA,uBAAuB,CAC7B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,UAAU,UAAQ,EAClB,SAAS,UAAQ,GACf,IAAI;IAIA,wBAAwB,CAC9B,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACb,IAAI;IAIA,qBAAqB,CAC3B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACb,IAAI;IAKP,OAAO,CAAC,iBAAiB;IAkHzB,OAAO,CAAC,kBAAkB;IAqB1B,OAAO,CAAC,cAAc;IAuGtB,OAAO,CAAC,YAAY;IAuFpB,OAAO,CAAC,UAAU;IA0BlB,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,UAAU;IAgDlB,OAAO,CAAC,YAAY;IAoDpB,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,gBAAgB;IAqDxB,OAAO,CAAC,qBAAqB;IAgC7B,OAAO,CAAC,uBAAuB;IAmB/B,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,oBAAoB;IA2E5B,OAAO,CAAC,cAAc;IAoEtB,OAAO,CAAC,eAAe;IAiLvB,OAAO,CAAC,oBAAoB;IAoD5B,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,sBAAsB;CAmI9B"}
1
+ {"version":3,"file":"CanvasRenderer.d.ts","sourceRoot":"","sources":["../../../../src/kurot/player/canvas/CanvasRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAgC,MAAM,gCAAgC,CAAC;AAC7F,OAAO,EAAE,MAAM,EAAyB,MAAM,yBAAyB,CAAC;AAKxE,OAAO,EAAE,QAAQ,EAAsB,MAAM,2BAA2B,CAAC;AAGzE,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAO9C,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAMpD,OAAO,EAAE,YAAY,EAAiB,MAAM,mBAAmB,CAAC;AAwBhE;;GAEG;AACH,qBAAa,cAAc;IAE1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4C;IAC7E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA8C;IACjF,OAAO,CAAC,WAAW,CAAY;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkC;IACpE,OAAO,CAAC,WAAW,CAAK;IAIxB;;OAEG;IACI,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IAiBnF,eAAe,CACrB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,UAAU,SAAI,GACZ,IAAI;IAUA,uBAAuB,CAC7B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,UAAU,UAAQ,EAClB,SAAS,UAAQ,GACf,IAAI;IAIA,wBAAwB,CAC9B,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACb,IAAI;IAIA,qBAAqB,CAC3B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACb,IAAI;IAKP,OAAO,CAAC,iBAAiB;IAkHzB,OAAO,CAAC,kBAAkB;IAqB1B,OAAO,CAAC,cAAc;IAuGtB,OAAO,CAAC,YAAY;IAuFpB,OAAO,CAAC,UAAU;IA0BlB,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,UAAU;IAgDlB,OAAO,CAAC,YAAY;IAqDpB,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,gBAAgB;IAqDxB,OAAO,CAAC,qBAAqB;IAgC7B,OAAO,CAAC,uBAAuB;IAmB/B,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,oBAAoB;IA2E5B,OAAO,CAAC,cAAc;IAoEtB,OAAO,CAAC,eAAe;IAsKvB,OAAO,CAAC,oBAAoB;IAoD5B,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,sBAAsB;CAmI9B"}
@@ -8,10 +8,10 @@ import { ColorMatrixFilter } from '../../filters/ColorMatrixFilter.js';
8
8
  import { GlowFilter } from '../../filters/GlowFilter.js';
9
9
  import { DropShadowFilter } from '../../filters/DropShadowFilter.js';
10
10
  import { HorizontalAlign } from '../../text/enums/HorizontalAlign.js';
11
- import { VerticalAlign } from '../../text/enums/VerticalAlign.js';
12
11
  import { TextFieldType } from '../../text/enums/TextFieldType.js';
13
12
  import { getFontString } from '../../text/TextMeasurer.js';
14
13
  import { getTextRenderPadding } from '../../text/TextRenderBounds.js';
14
+ import { getTextVerticalOffset } from '../../text/TextVerticalLayout.js';
15
15
  import { CanvasBuffer, hitTestBuffer } from './CanvasBuffer.js';
16
16
  import { getRenderContentBounds } from '../render-bounds.js';
17
17
  import { drawUnscaledBitmapFill } from '../bitmap-fill.js';
@@ -390,8 +390,8 @@ export class CanvasRenderer {
390
390
  ctx.imageSmoothingEnabled = text.smoothing;
391
391
  const x = offsetX + glyph.x + texture.offsetX;
392
392
  const y = offsetY + glyph.y + texture.offsetY;
393
- const width = texture.bitmapWidth * textureScaleFactor;
394
- const height = texture.bitmapHeight * textureScaleFactor;
393
+ const width = texture.scaleBitmapWidth;
394
+ const height = texture.scaleBitmapHeight;
395
395
  if (this._globalTint === 0xffffff) {
396
396
  ctx.drawImage(data.source, texture.bitmapX, texture.bitmapY, texture.bitmapWidth, texture.bitmapHeight, x, y, width, height);
397
397
  }
@@ -458,8 +458,9 @@ export class CanvasRenderer {
458
458
  const scaleY = destH / bitmap.textureHeight;
459
459
  const drawX = offsetX + bitmap.bitmapOffsetX * scaleX;
460
460
  const drawY = offsetY + bitmap.bitmapOffsetY * scaleY;
461
- const drawW = bitmap.bitmapWidth * textureScaleFactor * scaleX;
462
- const drawH = bitmap.bitmapHeight * textureScaleFactor * scaleY;
461
+ const pixelScale = bitmap.texture?.pixelScale ?? textureScaleFactor;
462
+ const drawW = bitmap.bitmapWidth * pixelScale * scaleX;
463
+ const drawH = bitmap.bitmapHeight * pixelScale * scaleY;
463
464
  if (this._globalTint === 0xffffff) {
464
465
  ctx.drawImage(bd.source, bitmap.bitmapX, bitmap.bitmapY, bitmap.bitmapWidth, bitmap.bitmapHeight, drawX, drawY, drawW, drawH);
465
466
  }
@@ -490,7 +491,7 @@ export class CanvasRenderer {
490
491
  });
491
492
  }
492
493
  drawScale9Bitmap(bitmap, grid, ctx, source, sourceX, sourceY, offsetX, offsetY, destW, destH) {
493
- const scale = textureScaleFactor;
494
+ const scale = bitmap.texture?.pixelScale ?? textureScaleFactor;
494
495
  const bw = bitmap.bitmapWidth;
495
496
  const bh = bitmap.bitmapHeight;
496
497
  const ox = bitmap.bitmapOffsetX;
@@ -738,22 +739,9 @@ export class CanvasRenderer {
738
739
  ctx.beginPath();
739
740
  ctx.rect(0 - padding, 0 - padding, width + padding * 2, height + padding * 2);
740
741
  ctx.clip();
741
- // ── Compute vertical offset ───────────────────────────────────────────
742
742
  const lines = tf.getLinesArr();
743
743
  const lineSpacing = tf.lineSpacing;
744
- let totalTextHeight = 0;
745
- for (let i = 0; i < lines.length; i++) {
746
- totalTextHeight += lines[i].height;
747
- if (i > 0)
748
- totalTextHeight += lineSpacing;
749
- }
750
- let verticalOffset = 0;
751
- if (tf.verticalAlign === VerticalAlign.MIDDLE) {
752
- verticalOffset = Math.max(0, (height - totalTextHeight) / 2);
753
- }
754
- else if (tf.verticalAlign === VerticalAlign.BOTTOM) {
755
- verticalOffset = Math.max(0, height - totalTextHeight);
756
- }
744
+ const verticalOffset = getTextVerticalOffset(tf);
757
745
  // ── ScrollV offset ────────────────────────────────────────────────────
758
746
  const inputActive = tf.type === TextFieldType.INPUT && tf.isTyping;
759
747
  const scrollOffset = tf.type === TextFieldType.INPUT && tf.multiline ? tf.$inputScrollY : tf.getScrollYOffset();
@@ -775,10 +763,9 @@ export class CanvasRenderer {
775
763
  for (let i = 0; i < lines.length; i++) {
776
764
  const line = lines[i];
777
765
  const h = line.height;
778
- drawY += h / 2;
779
- if (drawY + h / 2 <= 0 || drawY - h / 2 >= height) {
766
+ if (drawY + h <= 0 || drawY >= height) {
780
767
  characterIndex += line.charNum;
781
- drawY += h / 2 + lineSpacing;
768
+ drawY += h + lineSpacing;
782
769
  continue;
783
770
  }
784
771
  let lineX = 0;
@@ -805,9 +792,9 @@ export class CanvasRenderer {
805
792
  const stroke = style?.stroke ?? tf.stroke;
806
793
  const fontStr = getFontString(fontSize, fontFamily, bold, italic);
807
794
  ctx.font = fontStr;
808
- ctx.textBaseline = 'middle';
795
+ ctx.textBaseline = 'alphabetic';
809
796
  ctx.textAlign = 'left';
810
- const textY = drawY + (h - fontSize) / 2;
797
+ const textY = drawY + line.baseline;
811
798
  const elementStartIndex = characterIndex;
812
799
  const elementEndIndex = elementStartIndex + el.text.length;
813
800
  if (selectionVisible && selectionStart < elementEndIndex && selectionEnd > elementStartIndex) {
@@ -816,13 +803,13 @@ export class CanvasRenderer {
816
803
  const prefixWidth = ctx.measureText(el.text.substring(0, localStart)).width;
817
804
  const selectionWidth = ctx.measureText(el.text.substring(localStart, localEnd)).width;
818
805
  ctx.fillStyle = 'rgba(51, 144, 255, 0.55)';
819
- ctx.fillRect(lineX + prefixWidth, textY - fontSize / 2, selectionWidth, fontSize);
806
+ ctx.fillRect(lineX + prefixWidth, drawY, selectionWidth, h);
820
807
  }
821
- if (!caretLocated && tf.caretIndex >= elementStartIndex && tf.caretIndex <= elementEndIndex) {
808
+ if (inputActive && !caretLocated && tf.caretIndex >= elementStartIndex && tf.caretIndex <= elementEndIndex) {
822
809
  const localCaret = tf.caretIndex - elementStartIndex;
823
810
  caretX = lineX + ctx.measureText(el.text.substring(0, localCaret)).width;
824
- caretTop = textY - fontSize / 2;
825
- caretHeight = fontSize;
811
+ caretTop = drawY;
812
+ caretHeight = h;
826
813
  caretLocated = true;
827
814
  }
828
815
  if (stroke > 0) {
@@ -841,25 +828,27 @@ export class CanvasRenderer {
841
828
  const prefixWidth = ctx.measureText(el.text.substring(0, localStart)).width;
842
829
  const compositionWidth = ctx.measureText(el.text.substring(localStart, localEnd)).width;
843
830
  ctx.fillStyle = colorToString(textColor);
844
- ctx.fillRect(lineX + prefixWidth, textY + fontSize / 2, compositionWidth, 1);
831
+ const underlineY = Math.min(drawY + h - 1, textY + Math.max(1, line.inkDescent));
832
+ ctx.fillRect(lineX + prefixWidth, underlineY, compositionWidth, 1);
845
833
  }
846
834
  lineX += el.width;
847
835
  characterIndex = elementEndIndex;
848
836
  }
849
- if (!caretLocated && tf.caretIndex === lineStartIndex && line.elements.length === 0) {
837
+ if (inputActive && !caretLocated && tf.caretIndex === lineStartIndex && line.elements.length === 0) {
850
838
  caretX = lineStartX;
851
- caretTop = drawY - tf.size / 2;
839
+ caretTop = drawY;
840
+ caretHeight = h;
852
841
  caretLocated = true;
853
842
  }
854
- if (!caretLocated && tf.caretIndex >= characterIndex && tf.caretIndex < lineStartIndex + line.charNum) {
843
+ if (inputActive && !caretLocated && tf.caretIndex >= characterIndex && tf.caretIndex < lineStartIndex + line.charNum) {
855
844
  caretX = lineX;
856
- caretTop = drawY - tf.size / 2;
857
- caretHeight = tf.size;
845
+ caretTop = drawY;
846
+ caretHeight = h;
858
847
  caretLocated = true;
859
848
  }
860
849
  // charNum includes unpainted wrap spaces and the complete hard separator.
861
850
  characterIndex = lineStartIndex + line.charNum;
862
- drawY += h / 2 + lineSpacing;
851
+ drawY += h + lineSpacing;
863
852
  }
864
853
  // ── INPUT cursor ──────────────────────────────────────────────────────
865
854
  if (inputActive && tf.$caretVisible && selectionStart === selectionEnd && caretLocated) {