@kurot/core 2.1.1 → 2.2.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 (71) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +50 -2
  3. package/dist/kurot/display/DisplayObject.d.ts +2 -1
  4. package/dist/kurot/display/DisplayObject.d.ts.map +1 -1
  5. package/dist/kurot/display/DisplayObject.js.map +1 -1
  6. package/dist/kurot/player/canvas/CanvasRenderer.d.ts +2 -0
  7. package/dist/kurot/player/canvas/CanvasRenderer.d.ts.map +1 -1
  8. package/dist/kurot/player/canvas/CanvasRenderer.js +37 -1
  9. package/dist/kurot/player/canvas/CanvasRenderer.js.map +1 -1
  10. package/dist/kurot/player/pipes/BitmapTextPipe.d.ts +20 -0
  11. package/dist/kurot/player/pipes/BitmapTextPipe.d.ts.map +1 -0
  12. package/dist/kurot/player/pipes/BitmapTextPipe.js +27 -0
  13. package/dist/kurot/player/pipes/BitmapTextPipe.js.map +1 -0
  14. package/dist/kurot/player/pipes/index.d.ts +2 -0
  15. package/dist/kurot/player/pipes/index.d.ts.map +1 -1
  16. package/dist/kurot/player/pipes/index.js +1 -0
  17. package/dist/kurot/player/pipes/index.js.map +1 -1
  18. package/dist/kurot/player/webgl/WebGLRenderer.d.ts +1 -0
  19. package/dist/kurot/player/webgl/WebGLRenderer.d.ts.map +1 -1
  20. package/dist/kurot/player/webgl/WebGLRenderer.js +8 -0
  21. package/dist/kurot/player/webgl/WebGLRenderer.js.map +1 -1
  22. package/dist/kurot/resource/Resource.d.ts.map +1 -1
  23. package/dist/kurot/resource/Resource.js +4 -0
  24. package/dist/kurot/resource/Resource.js.map +1 -1
  25. package/dist/kurot/resource/ResourceItem.d.ts +1 -0
  26. package/dist/kurot/resource/ResourceItem.d.ts.map +1 -1
  27. package/dist/kurot/resource/ResourceItem.js +1 -0
  28. package/dist/kurot/resource/ResourceItem.js.map +1 -1
  29. package/dist/kurot/resource/analyzers/FontAnalyzer.d.ts +16 -0
  30. package/dist/kurot/resource/analyzers/FontAnalyzer.d.ts.map +1 -0
  31. package/dist/kurot/resource/analyzers/FontAnalyzer.js +75 -0
  32. package/dist/kurot/resource/analyzers/FontAnalyzer.js.map +1 -0
  33. package/dist/kurot/resource/analyzers/index.d.ts +1 -0
  34. package/dist/kurot/resource/analyzers/index.d.ts.map +1 -1
  35. package/dist/kurot/resource/analyzers/index.js +1 -0
  36. package/dist/kurot/resource/analyzers/index.js.map +1 -1
  37. package/dist/kurot/resource/index.d.ts +1 -0
  38. package/dist/kurot/resource/index.d.ts.map +1 -1
  39. package/dist/kurot/resource/index.js +1 -0
  40. package/dist/kurot/resource/index.js.map +1 -1
  41. package/dist/kurot/text/BitmapFont.d.ts +15 -21
  42. package/dist/kurot/text/BitmapFont.d.ts.map +1 -1
  43. package/dist/kurot/text/BitmapFont.js +59 -66
  44. package/dist/kurot/text/BitmapFont.js.map +1 -1
  45. package/dist/kurot/text/BitmapText.d.ts +29 -19
  46. package/dist/kurot/text/BitmapText.d.ts.map +1 -1
  47. package/dist/kurot/text/BitmapText.js +93 -141
  48. package/dist/kurot/text/BitmapText.js.map +1 -1
  49. package/dist/kurot/text/LineBreaks.d.ts +2 -1
  50. package/dist/kurot/text/LineBreaks.d.ts.map +1 -1
  51. package/dist/kurot/text/LineBreaks.js +13 -9
  52. package/dist/kurot/text/LineBreaks.js.map +1 -1
  53. package/dist/kurot/text/TextLineLayout.d.ts.map +1 -1
  54. package/dist/kurot/text/TextLineLayout.js +5 -12
  55. package/dist/kurot/text/TextLineLayout.js.map +1 -1
  56. package/dist/kurot/text/TextSegmentation.d.ts +7 -0
  57. package/dist/kurot/text/TextSegmentation.d.ts.map +1 -0
  58. package/dist/kurot/text/TextSegmentation.js +17 -0
  59. package/dist/kurot/text/TextSegmentation.js.map +1 -0
  60. package/dist/kurot/text/WordWrap.d.ts.map +1 -1
  61. package/dist/kurot/text/WordWrap.js +3 -11
  62. package/dist/kurot/text/WordWrap.js.map +1 -1
  63. package/dist/kurot/text/index.d.ts +1 -0
  64. package/dist/kurot/text/index.d.ts.map +1 -1
  65. package/dist/kurot/text/index.js.map +1 -1
  66. package/docs/ai-context.md +33 -9
  67. package/docs/architecture.md +332 -279
  68. package/docs/bitmap-fonts.md +85 -0
  69. package/docs/resource.md +185 -156
  70. package/docs/text-layout.md +71 -8
  71. package/package.json +4 -2
@@ -10,6 +10,10 @@ additional wrap opportunities.
10
10
  and closing punctuation rules rather than treating dictionary words as units.
11
11
  - Thai, Lao and Khmer add dictionary boundaries through the browser's
12
12
  `Intl.Segmenter`. The default Unicode rules remain independently testable.
13
+ - Since Core 2.2.1, optional word and emergency break opportunities are filtered
14
+ through `Intl.Segmenter` grapheme boundaries. Emoji ZWJ sequences, flags,
15
+ skin-tone modifiers, combining marks and conjuncts stay intact. A grapheme
16
+ wider than the field overflows intact rather than being split.
13
17
  - When an alphabetic word is wider than the entire line, emergency wrapping
14
18
  relaxes UAX #14's alphabetic rule LB28. Non-breaking spaces, narrow
15
19
  non-breaking spaces, word joiners and punctuation protection remain in force.
@@ -24,13 +28,18 @@ additional wrap opportunities.
24
28
  - In multiline mode, CRLF, CR, LF, VT, FF, NEL, line separator and paragraph
25
29
  separator force line breaks. A trailing hard separator retains a final empty line.
26
30
 
27
- `wordWrap = false` retains character-based wrapping in multiline mode. Since
31
+ `wordWrap = false` wraps between grapheme clusters in multiline mode since
32
+ Core 2.2.1; earlier releases wrapped between code points. Since
28
33
  Core 2.1.0, explicit `multiline = false` renders only the first
29
34
  hard-separated line without width wrapping. Dynamic text defaults to multiline;
30
35
  INPUT defaults to single-line until the flag is assigned. An unconstrained
31
36
  multiline field measures its hard-separated lines without automatic wrapping.
32
37
  Fixed height clips drawing rather than changing those measured lines.
33
38
 
39
+ Dictionary and grapheme segmentation follow the browser's `Intl` data. The
40
+ pinned Unicode 17.0 tables govern the line-break profile; they do not replace
41
+ the browser's grapheme implementation.
42
+
34
43
  ## Font readiness
35
44
 
36
45
  Load fonts before constructing or measuring text where possible. After a font
@@ -48,7 +57,11 @@ string is retained, including later hard-separated lines hidden in single-line
48
57
  mode. Existing files are not rewritten automatically.
49
58
 
50
59
  `WordWrap.tokenize()` remains a public word-segmentation utility; it is not the
51
- TextField line-break algorithm. `splitGraphemes()` is likewise independent.
60
+ TextField line-break algorithm. `splitGraphemes()` returns complete grapheme
61
+ clusters. These utilities and TextField share cached word/grapheme segmenters.
62
+ Layout computes grapheme end offsets once per constrained paragraph and reuses
63
+ them for ordinary and emergency wrapping. Text and segmentation results are
64
+ not cached globally.
52
65
 
53
66
  ## Validation
54
67
 
@@ -57,6 +70,18 @@ cases against the untailored profile. The compressed fixture includes its
57
70
  source URL, SHA-256 and Unicode license. Dictionary and emergency tailoring,
58
71
  multilingual width fitting, rich text, input offsets and rendering are tested
59
72
  separately in `test/TextWrapping.test.ts`.
73
+ `test/TextGraphemes.test.ts` covers complete-character wrapping, oversized
74
+ clusters, rich-text boundaries, hard separators and UTF-16 input offsets.
75
+ `test/LineBreaks.test.ts` also builds and executes a minified browser bundle
76
+ with `keepNames: false` to verify dictionary, alphabetic, grapheme and
77
+ non-breaking protection. The test environment provides browser APIs without
78
+ Node's `Buffer` global.
79
+
80
+ The 2.2.1 release check installs the packed Core with published UI 3.2.0 and
81
+ DragonBones 0.1.0, checks their declarations together, and renders a complete
82
+ minified browser bundle with `keepNames: false` in Canvas 2D, WebGL 1 and
83
+ WebGL 2. It verifies real-font grapheme layout, dictionary/emergency wrapping,
84
+ BitmapLabel glyphs and an animated native DragonBones mesh.
60
85
 
61
86
  The dependency bundles its Unicode property tables and uses no network or Node
62
87
  runtime APIs. Both WebGL text rasterization and Canvas rendering share this
@@ -65,13 +90,51 @@ regressions. No resource-manifest or CLI XML-format change is involved.
65
90
 
66
91
  ## Package dependencies
67
92
 
68
- UI 3.1.0 and ui-runtime 0.8.0 declare Core `^2.1.0` in their peer/development
69
- ranges; game 2.0.0 declares `^2.0.0`. Repository examples require Core `^2.1.0`.
70
- These ranges all accept 2.1.1, but installed lockfiles need updating to receive
71
- its nested scroll-clipping fix. CLI templates use `latest`.
93
+ Published UI 3.2.0 requires Core `^2.2.0` for BitmapLabel. Older UI 3.1.0 and
94
+ ui-runtime 0.8.2 declare Core `^2.1.0`; game 2.0.0 declares `^2.0.0`.
95
+ Existing example lockfiles still resolve Core 2.1.1 and UI 3.1.0; accepting a
96
+ version in a dependency range does not update an installed package.
97
+ DragonBones 0.1.0 declares Core `^2.1.1` and develops against published Core
98
+ 2.2.0. Its animation adapter does not depend on TextField wrapping changes.
99
+ CLI templates use `latest`.
72
100
  Label font shrinking calls `invalidateTextMetrics()` and requires Core 2.1.0
73
- or later. Core 2.1.1 preserves that text contract and does not require another
74
- UI, game or ui-runtime release.
101
+ or later. Core 2.2.1 preserves that TextField contract and remains accepted by
102
+ these existing peer ranges. Bitmap-font rendering is separate from TextField;
103
+ see [bitmap fonts](bitmap-fonts.md). The new UI BitmapLabel requires Core 2.2.0
104
+ and published UI 3.2.0; published UI 3.1.0 does not contain it.
105
+
106
+ Current consumers still need an installed-version update after 2.2.1 is published:
107
+
108
+ | Consumer | Current Core declaration | Locked or pinned Core | Required update |
109
+ | --- | --- | --- | --- |
110
+ | UI development | `^2.2.0` | 2.2.0 | Refresh the lockfile. |
111
+ | DragonBones development | `2.2.0`; peer `^2.1.1` | 2.2.0 | Update the development pin and lockfile. The peer already accepts 2.2.1. |
112
+ | Game / ui-runtime development | `^2.1.1` | 2.1.1 | Refresh the lockfiles. Their peers already accept 2.2.1. |
113
+ | Engine examples / tentax / copied Reskin project | `^2.1.1` | 2.1.1 | Refresh application lockfiles. |
114
+ | Editor | `2.1.1` | Exact pin 2.1.1 | Update the dependency and rebuild to deliver the fix. |
115
+ | Reskin application / milf-master template | `^2.1.1` | No pnpm lockfile | Update the installation; the declared range accepts 2.2.1. |
116
+
117
+ These consumer packages and applications are not changed by the Core patch.
118
+
119
+ ## Updating from Core 2.2.0 to 2.2.1
120
+
121
+ The 2.2.0 wrapper customizes rules by function name. Minifiers that rename
122
+ functions can silently disable alphabetic overflow tailoring and cause SA-script
123
+ dictionary wrapping to throw `Rule not found: "LB28"`. Core 2.2.1 customizes
124
+ the pinned dependency's rules by imported function identity, so this text path
125
+ no longer requires preserved function names. Kurot CLI's existing
126
+ `keepNames: true` setting remains useful for other name-based consumer APIs;
127
+ this patch does not change the CLI build contract.
128
+
129
+ Passing the official default corpus does not cover every real-text sequence.
130
+ The dependency exposes internal break opportunities for some composed emoji,
131
+ including family ZWJ sequences. Core 2.2.1 filters optional layout opportunities
132
+ through grapheme boundaries and uses those boundaries for character wrapping.
133
+ The untailored default Unicode profile remains unchanged. This affects
134
+ TextField layout without changing DragonBones playback or the separate
135
+ bitmap-font layout contract. No asset or project migration is required; update
136
+ the installed package and lockfile after publication. Source 2.2.1 is prepared
137
+ for publication; Core 2.2.0 is the published release.
75
138
 
76
139
  References: [UAX #14 revision 55](https://www.unicode.org/reports/tr14/tr14-55.html),
77
140
  [official corpus](https://www.unicode.org/Public/17.0.0/ucd/auxiliary/LineBreakTest.txt),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurot/core",
3
- "version": "2.1.1",
3
+ "version": "2.2.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",
@@ -44,6 +44,7 @@
44
44
  "devDependencies": {
45
45
  "@playwright/test": "1.62.1",
46
46
  "@types/node": "^22.0.0",
47
+ "esbuild": "^0.28.2",
47
48
  "fast-check": "^4.6.0",
48
49
  "happy-dom": "^20.8.9",
49
50
  "pixi.js": "8.20.0",
@@ -68,6 +69,7 @@
68
69
  "access": "public"
69
70
  },
70
71
  "dependencies": {
71
- "@cto.af/linebreak": "4.0.3"
72
+ "@cto.af/linebreak": "4.0.3",
73
+ "@kurot/bitmap-font": "^0.1.0"
72
74
  }
73
75
  }