@kurot/core 2.3.3 → 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 (69) hide show
  1. package/CHANGELOG.md +79 -3
  2. package/README.md +49 -13
  3. package/dist/kurot/display/DisplayObject.d.ts +26 -0
  4. package/dist/kurot/display/DisplayObject.d.ts.map +1 -1
  5. package/dist/kurot/display/DisplayObject.js +81 -9
  6. package/dist/kurot/display/DisplayObject.js.map +1 -1
  7. package/dist/kurot/display/texture/RenderTexture.d.ts +1 -0
  8. package/dist/kurot/display/texture/RenderTexture.d.ts.map +1 -1
  9. package/dist/kurot/display/texture/RenderTexture.js +4 -0
  10. package/dist/kurot/display/texture/RenderTexture.js.map +1 -1
  11. package/dist/kurot/display/texture/SpriteSheet.d.ts +4 -0
  12. package/dist/kurot/display/texture/SpriteSheet.d.ts.map +1 -1
  13. package/dist/kurot/display/texture/SpriteSheet.js +7 -3
  14. package/dist/kurot/display/texture/SpriteSheet.js.map +1 -1
  15. package/dist/kurot/display/texture/Texture.d.ts +14 -0
  16. package/dist/kurot/display/texture/Texture.d.ts.map +1 -1
  17. package/dist/kurot/display/texture/Texture.js +28 -6
  18. package/dist/kurot/display/texture/Texture.js.map +1 -1
  19. package/dist/kurot/player/bitmap-fill.js +1 -1
  20. package/dist/kurot/player/bitmap-fill.js.map +1 -1
  21. package/dist/kurot/player/canvas/CanvasRenderer.d.ts.map +1 -1
  22. package/dist/kurot/player/canvas/CanvasRenderer.js +27 -38
  23. package/dist/kurot/player/canvas/CanvasRenderer.js.map +1 -1
  24. package/dist/kurot/player/pipes/BitmapPipe.js +2 -2
  25. package/dist/kurot/player/pipes/BitmapPipe.js.map +1 -1
  26. package/dist/kurot/player/pipes/BitmapTextPipe.d.ts.map +1 -1
  27. package/dist/kurot/player/pipes/BitmapTextPipe.js +1 -2
  28. package/dist/kurot/player/pipes/BitmapTextPipe.js.map +1 -1
  29. package/dist/kurot/player/pipes/MaskPipe.d.ts.map +1 -1
  30. package/dist/kurot/player/pipes/MaskPipe.js +7 -1
  31. package/dist/kurot/player/pipes/MaskPipe.js.map +1 -1
  32. package/dist/kurot/player/webgl/WebGLRenderer.d.ts.map +1 -1
  33. package/dist/kurot/player/webgl/WebGLRenderer.js +4 -3
  34. package/dist/kurot/player/webgl/WebGLRenderer.js.map +1 -1
  35. package/dist/kurot/resource/analyzers/SheetAnalyzer.d.ts.map +1 -1
  36. package/dist/kurot/resource/analyzers/SheetAnalyzer.js +4 -1
  37. package/dist/kurot/resource/analyzers/SheetAnalyzer.js.map +1 -1
  38. package/dist/kurot/text/BitmapFont.d.ts.map +1 -1
  39. package/dist/kurot/text/BitmapFont.js +2 -0
  40. package/dist/kurot/text/BitmapFont.js.map +1 -1
  41. package/dist/kurot/text/TextField.d.ts.map +1 -1
  42. package/dist/kurot/text/TextField.js +7 -30
  43. package/dist/kurot/text/TextField.js.map +1 -1
  44. package/dist/kurot/text/TextLineLayout.d.ts.map +1 -1
  45. package/dist/kurot/text/TextLineLayout.js +44 -6
  46. package/dist/kurot/text/TextLineLayout.js.map +1 -1
  47. package/dist/kurot/text/TextMeasurer.d.ts +5 -0
  48. package/dist/kurot/text/TextMeasurer.d.ts.map +1 -1
  49. package/dist/kurot/text/TextMeasurer.js +10 -1
  50. package/dist/kurot/text/TextMeasurer.js.map +1 -1
  51. package/dist/kurot/text/TextRenderBounds.d.ts +1 -1
  52. package/dist/kurot/text/TextRenderBounds.d.ts.map +1 -1
  53. package/dist/kurot/text/TextRenderBounds.js +9 -2
  54. package/dist/kurot/text/TextRenderBounds.js.map +1 -1
  55. package/dist/kurot/text/TextVerticalLayout.d.ts +7 -0
  56. package/dist/kurot/text/TextVerticalLayout.d.ts.map +1 -0
  57. package/dist/kurot/text/TextVerticalLayout.js +23 -0
  58. package/dist/kurot/text/TextVerticalLayout.js.map +1 -0
  59. package/dist/kurot/text/types/ITextElement.d.ts +12 -0
  60. package/dist/kurot/text/types/ITextElement.d.ts.map +1 -1
  61. package/docs/ai-context.md +34 -4
  62. package/docs/architecture.md +8 -1
  63. package/docs/bitmap-fill.md +14 -7
  64. package/docs/bitmap-fonts.md +7 -3
  65. package/docs/centered-flips.md +34 -0
  66. package/docs/resource.md +5 -0
  67. package/docs/text-layout.md +41 -0
  68. package/docs/texture-density.md +96 -0
  69. package/package.json +1 -1
@@ -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":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAanE;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAc,EAAE,KAAa,EAAE,MAAc,EAAE,IAAwB;IAC7G,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC;IACtC,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC;IACxC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,IAAI,kBAAkB,CAAC;IAC/D,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QACxG,OAAO;IACR,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,KAAK,cAAc,CAAC,MAAM,CAAC;IACzD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC,CAAC;IACxF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC;IAEjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;QACtD,IAAI,UAAU,IAAI,CAAC;YAAE,SAAS;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;YACrD,IAAI,SAAS,IAAI,CAAC;gBAAE,SAAS;YAC7B,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC;YACpD,MAAM,KAAK,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC;YACnD,MAAM,WAAW,GAAG,SAAS,GAAG,KAAK,CAAC;YACtC,MAAM,YAAY,GAAG,UAAU,GAAG,KAAK,CAAC;YACxC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,GAAG,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAChG,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC3D,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QAC7F,CAAC;IACF,CAAC;AACF,CAAC"}
@@ -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';
@@ -129,8 +129,8 @@ export class CanvasRenderer {
129
129
  let childOffsetY;
130
130
  if (child.$useTranslate) {
131
131
  const m = child.$getMatrix();
132
- childOffsetX = offsetX + child.$x;
133
- childOffsetY = offsetY + child.$y;
132
+ childOffsetX = offsetX + m.tx;
133
+ childOffsetY = offsetY + m.ty;
134
134
  ctx.save();
135
135
  ctx.transform(m.a, m.b, m.c, m.d, childOffsetX, childOffsetY);
136
136
  childOffsetX = -child.$anchorOffsetX;
@@ -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) {