@kurot/core 2.4.0 → 2.5.1

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 +101 -2
  2. package/README.md +60 -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/TextBlockBounds.d.ts +12 -0
  38. package/dist/kurot/text/TextBlockBounds.d.ts.map +1 -0
  39. package/dist/kurot/text/TextBlockBounds.js +25 -0
  40. package/dist/kurot/text/TextBlockBounds.js.map +1 -0
  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 +12 -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 +22 -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 +31 -4
  62. package/docs/architecture.md +8 -1
  63. package/docs/bitmap-fill.md +9 -3
  64. package/docs/bitmap-fonts.md +7 -3
  65. package/docs/centered-flips.md +4 -4
  66. package/docs/resource.md +5 -0
  67. package/docs/text-layout.md +92 -0
  68. package/docs/texture-density.md +96 -0
  69. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TextLineLayout.js","sourceRoot":"","sources":["../../../src/kurot/text/TextLineLayout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TextLineLayout.js","sourceRoot":"","sources":["../../../src/kurot/text/TextLineLayout.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,11 @@
2
2
  * Measures the width of a text string using Canvas 2D.
3
3
  */
4
4
  export declare function measureText(text: string, fontFamily: string, fontSize: number, bold: boolean, italic: boolean): number;
5
+ /**
6
+ * Measures logical-pixel ink and font bounds relative to the alphabetic baseline.
7
+ * The caller owns caching and invalidation when fonts become ready.
8
+ */
9
+ export declare function measureTextMetrics(text: string, fontFamily: string, fontSize: number, bold: boolean, italic: boolean): TextMetrics;
5
10
  /**
6
11
  * Builds a CSS font string from the given parameters.
7
12
  */
@@ -1 +1 @@
1
- {"version":3,"file":"TextMeasurer.d.ts","sourceRoot":"","sources":["../../../src/kurot/text/TextMeasurer.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,wBAAgB,WAAW,CAC1B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,OAAO,GACb,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAE1G"}
1
+ {"version":3,"file":"TextMeasurer.d.ts","sourceRoot":"","sources":["../../../src/kurot/text/TextMeasurer.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,wBAAgB,WAAW,CAC1B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,OAAO,GACb,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,OAAO,GACb,WAAW,CAMb;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAE1G"}
@@ -23,9 +23,18 @@ function buildFontString(fontSize, fontFamily, bold, italic) {
23
23
  * Measures the width of a text string using Canvas 2D.
24
24
  */
25
25
  export function measureText(text, fontFamily, fontSize, bold, italic) {
26
+ return measureTextMetrics(text, fontFamily, fontSize, bold, italic).width;
27
+ }
28
+ /**
29
+ * Measures logical-pixel ink and font bounds relative to the alphabetic baseline.
30
+ * The caller owns caching and invalidation when fonts become ready.
31
+ */
32
+ export function measureTextMetrics(text, fontFamily, fontSize, bold, italic) {
26
33
  const ctx = getContext();
27
34
  ctx.font = buildFontString(fontSize, fontFamily, bold, italic);
28
- return ctx.measureText(text).width;
35
+ ctx.textBaseline = 'alphabetic';
36
+ ctx.textAlign = 'left';
37
+ return ctx.measureText(text);
29
38
  }
30
39
  /**
31
40
  * Builds a CSS font string from the given parameters.
@@ -1 +1 @@
1
- {"version":3,"file":"TextMeasurer.js","sourceRoot":"","sources":["../../../src/kurot/text/TextMeasurer.ts"],"names":[],"mappings":"AAAA,IAAI,YAA2C,CAAC;AAChD,IAAI,aAAmD,CAAC;AAExD,SAAS,UAAU;IAClB,IAAI,CAAC,aAAa,EAAE,CAAC;QACpB,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC;QACvB,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;QACxB,aAAa,GAAG,YAAY,CAAC,UAAU,CAAC,IAAI,CAAE,CAAC;IAChD,CAAC;IACD,OAAO,aAAa,CAAC;AACtB,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB,EAAE,UAAkB,EAAE,IAAa,EAAE,MAAe;IAC5F,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,MAAM;QAAE,IAAI,IAAI,SAAS,CAAC;IAC9B,IAAI,IAAI;QAAE,IAAI,IAAI,OAAO,CAAC;IAC1B,IAAI,IAAI,QAAQ,GAAG,KAAK,CAAC;IACzB,IAAI,IAAI,UAAU,CAAC;IACnB,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAC1B,IAAY,EACZ,UAAkB,EAClB,QAAgB,EAChB,IAAa,EACb,MAAe;IAEf,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/D,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,UAAkB,EAAE,IAAa,EAAE,MAAe;IACjG,OAAO,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5D,CAAC"}
1
+ {"version":3,"file":"TextMeasurer.js","sourceRoot":"","sources":["../../../src/kurot/text/TextMeasurer.ts"],"names":[],"mappings":"AAAA,IAAI,YAA2C,CAAC;AAChD,IAAI,aAAmD,CAAC;AAExD,SAAS,UAAU;IAClB,IAAI,CAAC,aAAa,EAAE,CAAC;QACpB,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC;QACvB,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;QACxB,aAAa,GAAG,YAAY,CAAC,UAAU,CAAC,IAAI,CAAE,CAAC;IAChD,CAAC;IACD,OAAO,aAAa,CAAC;AACtB,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB,EAAE,UAAkB,EAAE,IAAa,EAAE,MAAe;IAC5F,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,MAAM;QAAE,IAAI,IAAI,SAAS,CAAC;IAC9B,IAAI,IAAI;QAAE,IAAI,IAAI,OAAO,CAAC;IAC1B,IAAI,IAAI,QAAQ,GAAG,KAAK,CAAC;IACzB,IAAI,IAAI,UAAU,CAAC;IACnB,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAC1B,IAAY,EACZ,UAAkB,EAClB,QAAgB,EAChB,IAAa,EACb,MAAe;IAEf,OAAO,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC;AAC3E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CACjC,IAAY,EACZ,UAAkB,EAClB,QAAgB,EAChB,IAAa,EACb,MAAe;IAEf,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/D,GAAG,CAAC,YAAY,GAAG,YAAY,CAAC;IAChC,GAAG,CAAC,SAAS,GAAG,MAAM,CAAC;IACvB,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,UAAkB,EAAE,IAAa,EAAE,MAAe;IACjG,OAAO,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5D,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type { TextField } from './TextField.js';
2
2
  /**
3
- * Render-only margin for outlined dynamic text, including run-level strokes.
3
+ * Render-only margin for dynamic glyph overhang and run-level outlines.
4
4
  * Layout metrics and input viewports must not include this margin.
5
5
  */
6
6
  export declare function getTextRenderPadding(textField: TextField): number;
@@ -1 +1 @@
1
- {"version":3,"file":"TextRenderBounds.d.ts","sourceRoot":"","sources":["../../../src/kurot/text/TextRenderBounds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAejE"}
1
+ {"version":3,"file":"TextRenderBounds.d.ts","sourceRoot":"","sources":["../../../src/kurot/text/TextRenderBounds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAKhD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAuBjE"}
@@ -1,13 +1,23 @@
1
+ import { getTextBlockBounds } from './TextBlockBounds.js';
1
2
  import { TextFieldType } from './enums/TextFieldType.js';
3
+ import { VerticalAlign } from './enums/VerticalAlign.js';
2
4
  /**
3
- * Render-only margin for outlined dynamic text, including run-level strokes.
5
+ * Render-only margin for dynamic glyph overhang and run-level outlines.
4
6
  * Layout metrics and input viewports must not include this margin.
5
7
  */
6
8
  export function getTextRenderPadding(textField) {
7
9
  if (textField.type === TextFieldType.INPUT)
8
10
  return 0;
9
11
  let stroke = 0;
12
+ let overhang = 0;
13
+ const bounds = getTextBlockBounds(textField);
14
+ const baselineShift = textField.verticalAlign === VerticalAlign.MIDDLE
15
+ ? (textField.textHeight - bounds.top - bounds.bottom) / 2 : 0;
10
16
  for (const line of textField.getLinesArr()) {
17
+ if (line.inkAscent + line.inkDescent > 0) {
18
+ const baseline = line.baseline + baselineShift;
19
+ overhang = Math.max(overhang, line.inkAscent - baseline, baseline + line.inkDescent - line.height);
20
+ }
11
21
  for (const element of line.elements) {
12
22
  const value = element.style?.stroke ?? textField.stroke;
13
23
  if (Number.isFinite(value) && value > stroke) {
@@ -16,6 +26,6 @@ export function getTextRenderPadding(textField) {
16
26
  }
17
27
  }
18
28
  // Conservative ink margin covers glyph overhang and stroke antialiasing.
19
- return stroke > 0 ? Math.ceil(stroke * 2) + 2 : 0;
29
+ return (stroke > 0 ? Math.ceil(stroke * 2) + 2 : 0) + (overhang > 0 ? Math.ceil(overhang) + 1 : 0);
20
30
  }
21
31
  //# sourceMappingURL=TextRenderBounds.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextRenderBounds.js","sourceRoot":"","sources":["../../../src/kurot/text/TextRenderBounds.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAoB;IACxD,IAAI,SAAS,CAAC,IAAI,KAAK,aAAa,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC;IAErD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;QAC5C,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC;YACxD,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC;gBAC9C,MAAM,GAAG,KAAK,CAAC;YAChB,CAAC;QACF,CAAC;IACF,CAAC;IAED,yEAAyE;IACzE,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC"}
1
+ {"version":3,"file":"TextRenderBounds.js","sourceRoot":"","sources":["../../../src/kurot/text/TextRenderBounds.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAoB;IACxD,IAAI,SAAS,CAAC,IAAI,KAAK,aAAa,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC;IAErD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,aAAa,GAAG,SAAS,CAAC,aAAa,KAAK,aAAa,CAAC,MAAM;QACrE,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;QAC5C,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,aAAa,CAAC;YAC/C,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QACpG,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC;YACxD,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC;gBAC9C,MAAM,GAAG,KAAK,CAAC;YAChB,CAAC;QACF,CAAC;IACF,CAAC;IAED,yEAAyE;IACzE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpG,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { TextField } from './TextField.js';
2
+ /**
3
+ * Dynamic middle alignment centers the complete glyph block independently of
4
+ * multiline. Input retains nominal rows for stable editing geometry.
5
+ */
6
+ export declare function getTextVerticalOffset(field: TextField): number;
7
+ //# sourceMappingURL=TextVerticalLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextVerticalLayout.d.ts","sourceRoot":"","sources":["../../../src/kurot/text/TextVerticalLayout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAKhD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAa9D"}
@@ -0,0 +1,22 @@
1
+ import { getTextBlockBounds } from './TextBlockBounds.js';
2
+ import { TextFieldType } from './enums/TextFieldType.js';
3
+ import { VerticalAlign } from './enums/VerticalAlign.js';
4
+ /**
5
+ * Dynamic middle alignment centers the complete glyph block independently of
6
+ * multiline. Input retains nominal rows for stable editing geometry.
7
+ */
8
+ export function getTextVerticalOffset(field) {
9
+ const height = !isNaN(field.$explicitHeight) ? field.$explicitHeight : field.textHeight;
10
+ if (field.verticalAlign === VerticalAlign.MIDDLE) {
11
+ if (field.type === TextFieldType.DYNAMIC) {
12
+ const bounds = getTextBlockBounds(field);
13
+ return (height - bounds.top - bounds.bottom) / 2;
14
+ }
15
+ return Math.max(0, (height - field.textHeight) / 2);
16
+ }
17
+ if (field.verticalAlign === VerticalAlign.BOTTOM) {
18
+ return Math.max(0, height - field.textHeight);
19
+ }
20
+ return 0;
21
+ }
22
+ //# sourceMappingURL=TextVerticalLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextVerticalLayout.js","sourceRoot":"","sources":["../../../src/kurot/text/TextVerticalLayout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAgB;IACrD,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;IACxF,IAAI,KAAK,CAAC,aAAa,KAAK,aAAa,CAAC,MAAM,EAAE,CAAC;QAClD,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,CAAC,OAAO,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YACzC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,KAAK,CAAC,aAAa,KAAK,aAAa,CAAC,MAAM,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,CAAC,CAAC;AACV,CAAC"}
@@ -20,6 +20,18 @@ export interface IWTextElement extends ITextElement {
20
20
  export interface ILineElement {
21
21
  width: number;
22
22
  height: number;
23
+ /**
24
+ * Shared alphabetic baseline measured from the nominal line top, in logical pixels.
25
+ */
26
+ baseline: number;
27
+ /**
28
+ * Largest visible run extent above the shared baseline, excluding outlines.
29
+ */
30
+ inkAscent: number;
31
+ /**
32
+ * Largest visible run extent below the shared baseline, excluding outlines.
33
+ */
34
+ inkDescent: number;
23
35
  charNum: number;
24
36
  hasNextLine: boolean;
25
37
  elements: IWTextElement[];
@@ -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,22 @@
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.1 is prepared, not published, with dynamic middle alignment independent
4
+ of multiline. Core 2.5.0 remains the latest verified registry release
5
+ (2026-10-10). Read
4
6
  [centered flips](../../../docs/centered-flips.md) before changing transforms,
5
7
  reflection frames, authored flags or dependency adoption.
6
8
 
9
+ Core 2.5.0 adds independent Texture/SpriteSheet source density. Read [texture density](texture-density.md) before changing texture
10
+ dimensions or sheet loading. `resolution` defaults to 1 and is immutable;
11
+ sampling and page coordinates are physical, frame bounds/trim/grid are logical.
12
+ The default KUI kit uses 2× assets and requires this new Core implementation.
13
+
7
14
  Read this before exploring `src/`. It is a compressed map of the package so an
8
15
  agent unfamiliar with Kurot does not need to re-derive the architecture from
9
16
  scratch on every session. Treat the package source and its `src/index.ts`
10
17
  barrel as the authority for current behavior and exports.
11
18
 
12
- Package identity: `@kurot/core@2.4.0`, prepared in source and not published. It provides Kurot's scene graph,
19
+ Package identity: `@kurot/core@2.5.1`, prepared, not published. It provides Kurot's scene graph,
13
20
  events, rendering, text, resource, network and media runtime. Rendering uses a
14
21
  flat `InstructionSet + RenderPipe` pipeline. ES2022 / evergreen browsers only
15
22
  with `strict: true`. Two
@@ -47,7 +54,7 @@ src/kurot/
47
54
  │ push/pop scene integration in player/pipes/.
48
55
  ├── text/ TextField, BitmapText/BitmapFont, StageText (DOM overlay, INPUT mode only),
49
56
  │ HtmlTextParser, InputController, TextMeasurer, TextSegmentation,
50
- │ LineBreaks, TextLineLayout, WordWrap.
57
+ │ LineBreaks, TextLineLayout, TextBlockBounds, TextVerticalLayout, WordWrap.
51
58
  ├── resource/ Resource class + `resource` singleton, ResourceLoader, analyzers/
52
59
  │ (Image/Json/Text/Sound/Sheet/Font). Async, resource.json-driven (RES-compatible).
53
60
  ├── net/ HttpRequest, ImageLoader. Low-level; resource/analyzers build on these.
@@ -86,6 +93,10 @@ colocated under `examples/benchmark/`; none are exported from `index.ts`.
86
93
  content, not the clip. WebGL's nested/rotated stencil path must use the same
87
94
  viewport origin as its axis-aligned scissor path. Rectangle masks retain
88
95
  their own local x/y. See `player/pipes/MaskPipe.ts`.
96
+ - The Core 2.5.0 axis-aligned WebGL scissor correction encloses fractional
97
+ physical bounds with floor(left/top) and ceil(right/bottom), then subtracts
98
+ those integer edges. Do not truncate position and size independently: this
99
+ cuts boundary pixels from scaled ItemRenderer skins. Stencil clips are unchanged.
89
100
  - `CanvasRenderer` is not purely a fallback. The WebGL backend depends on it
90
101
  internally to rasterize Graphics/Text to offscreen canvases before texture
91
102
  upload, and to snapshot `RenderTexture`. Don't reason about it as dead code
@@ -217,7 +228,7 @@ Re-export order: `events`, `geom`, `utils`, `display`, `net`, `filters`,
217
228
  | Change how instructions are built/executed | `player/webgl/WebGLRenderer.ts`, `player/InstructionSet.ts` |
218
229
  | Add a new resource type/parser | `resource/analyzers/`, register in `Resource.ts` |
219
230
  | Debug a texture-batching issue | `player/webgl/MultiTextureBatcher.ts`, `player/webgl/WebGLDrawCmdManager.ts` |
220
- | Change text layout/wrapping | `text/LineBreaks.ts`, `text/TextLineLayout.ts`, `text/TextSegmentation.ts`, `text/TextMeasurer.ts`; `docs/text-layout.md` |
231
+ | Change text layout/wrapping | `text/LineBreaks.ts`, `text/TextLineLayout.ts`, `text/TextBlockBounds.ts`, `text/TextVerticalLayout.ts`, `text/TextSegmentation.ts`, `text/TextMeasurer.ts`; `docs/text-layout.md` |
221
232
  | Understand dirty-flag propagation | `display/DisplayObject.ts` (`$markDirty`, `$cacheDirtyUp`, `$renderDirtyUp`) |
222
233
  | Run perf tests | `examples/benchmark/`, `pnpm benchmark`; automated Kurot/PixiJS/Egret comparison via `pnpm benchmark:compare` |
223
234
 
@@ -230,6 +241,22 @@ vertices, UVs, or indices, call updateVertices(). WebGL keeps Mesh indices
230
241
  separate from quad indices and splits oversized meshes into ordered batches
231
242
  with local index remapping (player/webgl/split-mesh.ts).
232
243
 
244
+ ## Text alignment in 2.5.1
245
+
246
+ `TextLineLayout.ts` caches alphabetic `baseline` and visible `inkAscent` /
247
+ `inkDescent` per line. `TextBlockBounds.ts` caches the union of row glyph bounds,
248
+ using nominal rows for blank lines. `TextVerticalLayout.ts` centers the entire
249
+ dynamic block in either line mode. Multiline only controls line generation;
250
+ input/top/bottom retain nominal alignment with content-independent font frames.
251
+ Relative row baselines and spacing stay stable, but a dynamic middle block can
252
+ translate when its glyph extents change. Canvas, WebGL
253
+ rasterization and link hit testing share the offset. Render bounds add glyph
254
+ margin without changing measurement, input or external clip boundaries. See
255
+ [text layout](text-layout.md#middle-alignment-independent-of-line-mode-core-251).
256
+ Published Core 2.5.0 centers only single-line dynamic ink. Version 2.5.1 is
257
+ prepared, not published; existing consumer peers accept it without SDK bumps.
258
+ Adoption requires an explicit installation/lock update and rebuild after release.
259
+
233
260
  ## Text layout in 2.0.1
234
261
 
235
262
  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 (published; registry version metadata verified on 2026-10-10). 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,98 @@ 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
+ ## Middle alignment independent of line mode (Core 2.5.1)
44
+
45
+ Core 2.5.1 is prepared, not published. The current verified registry release is
46
+ 2.5.0. Its single-line-only visual centering is described in the following section.
47
+
48
+ `multiline` controls hard breaks and width wrapping. Dynamic
49
+ `verticalAlign = "middle"` centers the complete laid-out glyph block in either
50
+ line mode. Identical single-row content, font and bounds produce identical
51
+ placement with `multiline = true` or `false`, including automatic height.
52
+ Multiple rows receive one shared translation; their relative alphabetic baselines
53
+ and line spacing are preserved. Rich runs and fallback glyphs participate in the
54
+ same block bounds. Each blank/whitespace-only row contributes its nominal height,
55
+ including leading and trailing blank rows. An entirely blank block uses those
56
+ nominal rows. Outlines remain render-only and do not affect alignment.
57
+
58
+ ```ts
59
+ textField.multiline = true;
60
+ textField.verticalAlign = 'middle';
61
+ textField.text = 'First line\nSecond line';
62
+ ```
63
+
64
+ The visible block is centered within the explicit height, or the nominal content
65
+ height when height is automatic. An overflowing dynamic block remains centered;
66
+ ordinary viewport clipping and scrolling still apply. Changing the outer glyph
67
+ extents can translate the complete block, without changing its row baselines or
68
+ distances. The cache reuses block bounds until font/content/wrapping/spacing
69
+ invalidation replaces the line layout.
70
+
71
+ INPUT continues to align its stable editing rows in either line mode. Caret,
72
+ selection, composition underline and pointer-to-character mapping use those rows,
73
+ so changing glyphs cannot move the editing frame. `top` and `bottom` retain their
74
+ nominal-row semantics. `textHeight`, `measureText()`, automatic dimensions, font
75
+ fitting and wrapping measurements retain their existing contracts.
76
+
77
+ Canvas, WebGL text rasterization, link hit tests and glyph/outline capture margins
78
+ share the block alignment. External masks/scrollRect and input viewports keep
79
+ their authored clip boundaries. No new public property, runtime dependency or
80
+ XML/resource format is introduced. Existing multiline dynamic middle-aligned
81
+ captions can move compared with 2.5.0; adopt the released Core patch and rebuild
82
+ the application to receive the change. Existing SDK peers accept the patch.
83
+
84
+ Unit checks cover both line modes, complete paragraphs, mixed-size rich text,
85
+ blank rows, font/spacing invalidation, top/bottom, short viewports, links and
86
+ single/multiline input caret/selection. The minified browser checks compare
87
+ independent Canvas measurements and actual pixels in Canvas and WebGL 1/2 at
88
+ 1×/2×, including multilingual text, wrapping, caches, outlines, caret, selection,
89
+ composition decoration and input character hits.
90
+
91
+ ## Visual centering and stable baselines (Core 2.5.0)
92
+
93
+ This section records the published 2.5.0 behavior. Version 2.5.1 extends dynamic
94
+ middle alignment to multiple rows as described above; input and top/bottom retain
95
+ the contracts below.
96
+
97
+ Canvas and WebGL use the same alphabetic baseline and logical-pixel Canvas
98
+ `TextMetrics`. Each cached line records `baseline`, `inkAscent` and `inkDescent`;
99
+ rich runs share that baseline, even when their sizes or font families differ.
100
+ Visible bounds include fallback glyphs, accents and combining marks. No language
101
+ or operating-system offset table is used.
102
+
103
+ - Dynamic text with `multiline = false` and `verticalAlign = "middle"` centers
104
+ the union of visible run ink in the field. Empty/whitespace-only lines use
105
+ the nominal line box. Changing a button caption may change its baseline so
106
+ its visible glyphs remain centered.
107
+ - Multiline text and INPUT retain font-based baselines. Font-frame bounds are
108
+ measured with an empty string per font configuration, independently of the
109
+ current caption and its fallback glyphs. Empty lines retain the same frame.
110
+ Input caret/selection use the nominal row; composition underlines stay inside
111
+ the viewport. Top/bottom alignment also uses nominal line boxes.
112
+ - `textHeight`, `measureText()`, wrapping, row spacing and layout bounds retain
113
+ their nominal size contract. Dynamic glyph overhang is added only to render
114
+ captures, together with outlines; INPUT and external clips remain exact.
115
+ - Measurements are reused with the TextField line cache. After loading/replacing
116
+ a font, call `invalidateTextMetrics()` through the existing readiness path.
117
+ Fonts and browser rasterization can differ across systems; centering follows
118
+ the actual selected glyphs rather than promising identical pixels.
119
+
120
+ See the [Canvas TextMetrics contract](https://html.spec.whatwg.org/multipage/canvas.html#textmetrics).
121
+ The correction is included in published Core 2.5.0; it is not in
122
+ published Core 2.4.0. There is no new alignment
123
+ property, runtime dependency or XML format. Default KUI single-line control
124
+ labels use the existing flags with symmetric padding. Adopt Core 2.5.0 and rebuild to receive this behavior; SDK peers need no
125
+ incidental change.
126
+
127
+ `test/TextVerticalLayout.test.ts` covers ink centering, mixed sizes, stable input
128
+ and paragraph baselines, link hits, blank rows, overhang and font invalidation.
129
+ The minified `text-alignment.spec.ts` compares 18 multilingual strings in regular
130
+ and bold faces against an independent Canvas reference in Canvas/WebGL 1/2 at
131
+ 1×/2×, including rich runs, outlines, nested caches and tight Thai/Hindi rows.
132
+ The continuous-frame checks also cover restoring the root WebGL target after
133
+ its initial offscreen allocation.
134
+
43
135
  ## Independent measurement (Core 2.3.0)
44
136
 
45
137
  `textField.measureText(width = NaN)` measures complete content under a separate
@@ -0,0 +1,96 @@
1
+ # Texture density
2
+
3
+ This API is included in published Core 2.5.0, with registry version metadata
4
+ verified on 2026-10-10. 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.1",
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",