@glassly/miniapp 0.3.0-dev.1 → 0.3.0-dev.460

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 (255) hide show
  1. package/README.md +219 -74
  2. package/dist/background/index.d.ts +14 -8
  3. package/dist/background/index.d.ts.map +1 -1
  4. package/dist/background/index.js +4 -0
  5. package/dist/background/index.js.map +1 -1
  6. package/dist/background/register.d.ts +1 -1
  7. package/dist/background/register.js +1 -1
  8. package/dist/display/index.d.ts +23 -0
  9. package/dist/display/index.d.ts.map +1 -0
  10. package/dist/display/index.js +17 -0
  11. package/dist/display/index.js.map +1 -0
  12. package/dist/display/measurer/TextMeasurer.d.ts +160 -0
  13. package/dist/display/measurer/TextMeasurer.d.ts.map +1 -0
  14. package/dist/display/measurer/TextMeasurer.js +272 -0
  15. package/dist/display/measurer/TextMeasurer.js.map +1 -0
  16. package/dist/display/measurer/index.d.ts +10 -0
  17. package/dist/display/measurer/index.d.ts.map +1 -0
  18. package/dist/display/measurer/index.js +11 -0
  19. package/dist/display/measurer/index.js.map +1 -0
  20. package/dist/display/measurer/script-detection.d.ts +53 -0
  21. package/dist/display/measurer/script-detection.d.ts.map +1 -0
  22. package/dist/display/measurer/script-detection.js +184 -0
  23. package/dist/display/measurer/script-detection.js.map +1 -0
  24. package/dist/display/pixelArt.d.ts +22 -0
  25. package/dist/display/pixelArt.d.ts.map +1 -0
  26. package/dist/display/pixelArt.js +126 -0
  27. package/dist/display/pixelArt.js.map +1 -0
  28. package/dist/display/profiles/g1.d.ts +33 -0
  29. package/dist/display/profiles/g1.d.ts.map +1 -0
  30. package/dist/display/profiles/g1.js +214 -0
  31. package/dist/display/profiles/g1.js.map +1 -0
  32. package/dist/display/profiles/g2.d.ts +13 -0
  33. package/dist/display/profiles/g2.d.ts.map +1 -0
  34. package/dist/display/profiles/g2.js +34 -0
  35. package/dist/display/profiles/g2.js.map +1 -0
  36. package/dist/display/profiles/index.d.ts +12 -0
  37. package/dist/display/profiles/index.d.ts.map +1 -0
  38. package/dist/display/profiles/index.js +15 -0
  39. package/dist/display/profiles/index.js.map +1 -0
  40. package/dist/display/profiles/nex.d.ts +10 -0
  41. package/dist/display/profiles/nex.d.ts.map +1 -0
  42. package/dist/display/profiles/nex.js +150 -0
  43. package/dist/display/profiles/nex.js.map +1 -0
  44. package/dist/display/profiles/types.d.ts +103 -0
  45. package/dist/display/profiles/types.d.ts.map +1 -0
  46. package/dist/display/profiles/types.js +2 -0
  47. package/dist/display/profiles/types.js.map +1 -0
  48. package/dist/display/profiles/z100.d.ts +33 -0
  49. package/dist/display/profiles/z100.d.ts.map +1 -0
  50. package/dist/display/profiles/z100.js +182 -0
  51. package/dist/display/profiles/z100.js.map +1 -0
  52. package/dist/display/scene/types.d.ts +292 -0
  53. package/dist/display/scene/types.d.ts.map +1 -0
  54. package/dist/display/scene/types.js +0 -0
  55. package/dist/display/scene/types.js.map +1 -0
  56. package/dist/display/wrapper/TextWrapper.d.ts +102 -0
  57. package/dist/display/wrapper/TextWrapper.d.ts.map +1 -0
  58. package/dist/display/wrapper/TextWrapper.js +469 -0
  59. package/dist/display/wrapper/TextWrapper.js.map +1 -0
  60. package/dist/display/wrapper/index.d.ts +12 -0
  61. package/dist/display/wrapper/index.d.ts.map +1 -0
  62. package/dist/display/wrapper/index.js +12 -0
  63. package/dist/display/wrapper/index.js.map +1 -0
  64. package/dist/display/wrapper/types.d.ts +75 -0
  65. package/dist/display/wrapper/types.d.ts.map +1 -0
  66. package/dist/display/wrapper/types.js +11 -0
  67. package/dist/display/wrapper/types.js.map +1 -0
  68. package/dist/globals.d.ts +5 -5
  69. package/dist/globals.d.ts.map +1 -1
  70. package/dist/globals.js +1 -1
  71. package/dist/globals.js.map +1 -1
  72. package/dist/hardware.d.ts +4 -18
  73. package/dist/hardware.d.ts.map +1 -1
  74. package/dist/hardware.js +2 -13
  75. package/dist/hardware.js.map +1 -1
  76. package/dist/index.d.ts +16 -10
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +3 -1
  79. package/dist/index.js.map +1 -1
  80. package/dist/knownApps.d.ts +26 -0
  81. package/dist/knownApps.d.ts.map +1 -0
  82. package/dist/knownApps.js +140 -0
  83. package/dist/knownApps.js.map +1 -0
  84. package/dist/mirror/canvas.d.ts +22 -0
  85. package/dist/mirror/canvas.d.ts.map +1 -0
  86. package/dist/mirror/canvas.js +311 -0
  87. package/dist/mirror/canvas.js.map +1 -0
  88. package/dist/mirror/geometry.d.ts +69 -0
  89. package/dist/mirror/geometry.d.ts.map +1 -0
  90. package/dist/mirror/geometry.js +75 -0
  91. package/dist/mirror/geometry.js.map +1 -0
  92. package/dist/mirror/index.d.ts +3 -0
  93. package/dist/mirror/index.d.ts.map +1 -0
  94. package/dist/mirror/index.js +2 -0
  95. package/dist/mirror/index.js.map +1 -0
  96. package/dist/mirror/types.d.ts +40 -0
  97. package/dist/mirror/types.d.ts.map +1 -0
  98. package/dist/mirror/types.js +2 -0
  99. package/dist/mirror/types.js.map +1 -0
  100. package/dist/modules/auth.d.ts +1 -1
  101. package/dist/modules/auth.d.ts.map +1 -1
  102. package/dist/modules/auth.js +2 -2
  103. package/dist/modules/auth.js.map +1 -1
  104. package/dist/modules/compass.d.ts +47 -0
  105. package/dist/modules/compass.d.ts.map +1 -0
  106. package/dist/modules/compass.js +39 -0
  107. package/dist/modules/compass.js.map +1 -0
  108. package/dist/modules/display.d.ts +192 -8
  109. package/dist/modules/display.d.ts.map +1 -1
  110. package/dist/modules/display.js +40 -3
  111. package/dist/modules/display.js.map +1 -1
  112. package/dist/modules/events.d.ts +30 -2
  113. package/dist/modules/events.d.ts.map +1 -1
  114. package/dist/modules/events.js.map +1 -1
  115. package/dist/modules/input.d.ts +40 -1
  116. package/dist/modules/input.d.ts.map +1 -1
  117. package/dist/modules/input.js +45 -1
  118. package/dist/modules/input.js.map +1 -1
  119. package/dist/modules/latest-render-scheduler.d.ts +19 -0
  120. package/dist/modules/latest-render-scheduler.d.ts.map +1 -0
  121. package/dist/modules/latest-render-scheduler.js +54 -0
  122. package/dist/modules/latest-render-scheduler.js.map +1 -0
  123. package/dist/modules/lightSensor.d.ts +44 -0
  124. package/dist/modules/lightSensor.d.ts.map +1 -0
  125. package/dist/modules/lightSensor.js +33 -0
  126. package/dist/modules/lightSensor.js.map +1 -0
  127. package/dist/modules/mic.d.ts +3 -2
  128. package/dist/modules/mic.d.ts.map +1 -1
  129. package/dist/modules/mic.js +3 -2
  130. package/dist/modules/mic.js.map +1 -1
  131. package/dist/modules/miniapps.d.ts +2 -0
  132. package/dist/modules/miniapps.d.ts.map +1 -1
  133. package/dist/modules/miniapps.js.map +1 -1
  134. package/dist/modules/mirror.d.ts +16 -0
  135. package/dist/modules/mirror.d.ts.map +1 -0
  136. package/dist/modules/mirror.js +40 -0
  137. package/dist/modules/mirror.js.map +1 -0
  138. package/dist/modules/mono-text-rows.d.ts +20 -0
  139. package/dist/modules/mono-text-rows.d.ts.map +1 -0
  140. package/dist/modules/mono-text-rows.js +26 -0
  141. package/dist/modules/mono-text-rows.js.map +1 -0
  142. package/dist/modules/navigation.d.ts.map +1 -1
  143. package/dist/modules/navigation.js +21 -14
  144. package/dist/modules/navigation.js.map +1 -1
  145. package/dist/modules/phone.d.ts +26 -1
  146. package/dist/modules/phone.d.ts.map +1 -1
  147. package/dist/modules/phone.js +28 -0
  148. package/dist/modules/phone.js.map +1 -1
  149. package/dist/modules/settings.d.ts +45 -0
  150. package/dist/modules/settings.d.ts.map +1 -0
  151. package/dist/modules/settings.js +54 -0
  152. package/dist/modules/settings.js.map +1 -0
  153. package/dist/modules/system.d.ts +21 -0
  154. package/dist/modules/system.d.ts.map +1 -1
  155. package/dist/modules/system.js +12 -0
  156. package/dist/modules/system.js.map +1 -1
  157. package/dist/modules/transcription.d.ts +3 -2
  158. package/dist/modules/transcription.d.ts.map +1 -1
  159. package/dist/modules/transcription.js +3 -2
  160. package/dist/modules/transcription.js.map +1 -1
  161. package/dist/protocol.d.ts +65 -5
  162. package/dist/protocol.d.ts.map +1 -1
  163. package/dist/protocol.js +66 -5
  164. package/dist/protocol.js.map +1 -1
  165. package/dist/react/MirrorCanvas.d.ts +10 -0
  166. package/dist/react/MirrorCanvas.d.ts.map +1 -0
  167. package/dist/react/MirrorCanvas.js +23 -0
  168. package/dist/react/MirrorCanvas.js.map +1 -0
  169. package/dist/react/index.d.ts +2 -0
  170. package/dist/react/index.d.ts.map +1 -1
  171. package/dist/react/index.js +1 -0
  172. package/dist/react/index.js.map +1 -1
  173. package/dist/react/useColorScheme.d.ts +2 -3
  174. package/dist/react/useColorScheme.d.ts.map +1 -1
  175. package/dist/react/useColorScheme.js +15 -8
  176. package/dist/react/useColorScheme.js.map +1 -1
  177. package/dist/react/useRpc.js +2 -2
  178. package/dist/react/useRpc.js.map +1 -1
  179. package/dist/react/useSafeArea.d.ts.map +1 -1
  180. package/dist/react/useSafeArea.js +2 -2
  181. package/dist/react/useSafeArea.js.map +1 -1
  182. package/dist/session.d.ts +50 -4
  183. package/dist/session.d.ts.map +1 -1
  184. package/dist/session.js +35 -6
  185. package/dist/session.js.map +1 -1
  186. package/dist/transport/auto.d.ts +2 -2
  187. package/dist/transport/auto.js +2 -2
  188. package/dist/transport/dispatch.d.ts +1 -1
  189. package/dist/transport/dispatch.js +1 -1
  190. package/dist/transport/mock.d.ts +4 -4
  191. package/dist/transport/mock.d.ts.map +1 -1
  192. package/dist/transport/mock.js +31 -7
  193. package/dist/transport/mock.js.map +1 -1
  194. package/dist/ui/index.d.ts +2 -0
  195. package/dist/ui/index.d.ts.map +1 -1
  196. package/dist/ui/index.js +1 -0
  197. package/dist/ui/index.js.map +1 -1
  198. package/package.json +19 -3
  199. package/src/background/index.ts +26 -4
  200. package/src/background/register.ts +1 -1
  201. package/src/display/index.ts +83 -0
  202. package/src/display/measurer/TextMeasurer.ts +346 -0
  203. package/src/display/measurer/index.ts +21 -0
  204. package/src/display/measurer/script-detection.ts +218 -0
  205. package/src/display/pixelArt.ts +141 -0
  206. package/src/display/profiles/g1.ts +237 -0
  207. package/src/display/profiles/g2.ts +39 -0
  208. package/src/display/profiles/index.ts +28 -0
  209. package/src/display/profiles/nex.ts +166 -0
  210. package/src/display/profiles/types.ts +132 -0
  211. package/src/display/profiles/z100.ts +198 -0
  212. package/src/display/scene/types.ts +335 -0
  213. package/src/display/wrapper/TextWrapper.ts +546 -0
  214. package/src/display/wrapper/index.ts +15 -0
  215. package/src/display/wrapper/types.ts +102 -0
  216. package/src/globals.ts +5 -5
  217. package/src/hardware.ts +6 -21
  218. package/src/index.ts +34 -6
  219. package/src/knownApps.ts +170 -0
  220. package/src/mirror/canvas.ts +322 -0
  221. package/src/mirror/geometry.ts +128 -0
  222. package/src/mirror/index.ts +2 -0
  223. package/src/mirror/types.ts +38 -0
  224. package/src/modules/auth.ts +2 -2
  225. package/src/modules/compass.ts +69 -0
  226. package/src/modules/display.ts +222 -12
  227. package/src/modules/events.ts +27 -1
  228. package/src/modules/input.ts +55 -2
  229. package/src/modules/latest-render-scheduler.ts +55 -0
  230. package/src/modules/lightSensor.ts +61 -0
  231. package/src/modules/mic.ts +3 -2
  232. package/src/modules/miniapps.ts +2 -0
  233. package/src/modules/mirror.ts +42 -0
  234. package/src/modules/mono-text-rows.ts +30 -0
  235. package/src/modules/navigation.ts +20 -14
  236. package/src/modules/phone.ts +40 -1
  237. package/src/modules/settings.ts +64 -0
  238. package/src/modules/system.ts +30 -1
  239. package/src/modules/transcription.ts +3 -2
  240. package/src/protocol.ts +72 -5
  241. package/src/react/MirrorCanvas.tsx +35 -0
  242. package/src/react/index.ts +3 -0
  243. package/src/react/useColorScheme.ts +17 -8
  244. package/src/react/useRpc.ts +2 -2
  245. package/src/react/useSafeArea.ts +2 -2
  246. package/src/session.ts +78 -8
  247. package/src/transport/auto.ts +2 -2
  248. package/src/transport/dispatch.ts +1 -1
  249. package/src/transport/mock.ts +42 -11
  250. package/src/ui/index.ts +3 -0
  251. package/dist/modules/heading.d.ts +0 -16
  252. package/dist/modules/heading.d.ts.map +0 -1
  253. package/dist/modules/heading.js +0 -20
  254. package/dist/modules/heading.js.map +0 -1
  255. package/src/modules/heading.ts +0 -23
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * registerMiniapp — entry hook for the background JSContext.
3
3
  *
4
- * The GlasslyJS host loads the polyfill (which installs __dispatch /
4
+ * The JSRuntime host loads the polyfill (which installs __dispatch /
5
5
  * __deliver / timers / fetch / etc.), then evaluates the miniapp's
6
6
  * background bundle. After both scripts have evaluated successfully,
7
7
  * the host delivers a single `{kind: "init", sessionId}` envelope.
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @glassly/miniapp/display — the phone-side text and scene primitives a
3
+ * miniapp needs to lay out a frame the way the host measures it: the glasses'
4
+ * display profiles (glyph widths, line heights), pixel-accurate measurement
5
+ * and wrapping, pixel-art icons as scene images, and the scene element types
6
+ * the host's render pipeline consumes. Pure TypeScript with no host imports;
7
+ * the engine's scene pipeline (`processScene`) uses these same modules, so a
8
+ * miniapp that wraps text with them gets the rows the glasses will draw.
9
+ */
10
+ export type { DisplayProfile, FontMetrics, UniformScriptWidths, FallbackConfig, DisplayConstraints, ScriptType, } from "./profiles";
11
+ export { G1_PROFILE, G1_PROFILE_LEGACY, G1_HYPHEN_WIDTH_PX, G1_SPACE_WIDTH_PX, G2_PROFILE, G2_HYPHEN_WIDTH_PX, G2_SPACE_WIDTH_PX, Z100_PROFILE, Z100_HYPHEN_WIDTH_PX, Z100_SPACE_WIDTH_PX, NEX_PROFILE, NEX_HYPHEN_WIDTH_PX, NEX_SPACE_WIDTH_PX, } from "./profiles";
12
+ export { TextMeasurer } from "./measurer";
13
+ export type { CharMeasurement, TextMeasurement } from "./measurer";
14
+ export { detectScript, isCJKCharacter, isKoreanCharacter, isUniformWidthScript, isUnsupportedScript, needsHyphenForBreak, SCRIPT_RANGES, } from "./measurer";
15
+ export { TextWrapper, DEFAULT_WRAP_OPTIONS } from "./wrapper";
16
+ export type { WrapOptions, WrapResult, LineMetrics, BreakMode } from "./wrapper";
17
+ export { pixelArtElement, pixelArtPng, pixelArtSize, pixelLevel } from "./pixelArt";
18
+ export type { PixelArt } from "./pixelArt";
19
+ export type { FrameElement, SceneAnchor, SceneBox, SceneBoxInput, SceneBreakMode, SceneChange, SceneDisplayCapabilities, SceneElementInput, SceneElementType, SceneFrame, SceneImageStyle, ScenePoint, SceneProcessResult, SceneRectStyle, SceneShapeStyle, SceneStrokeStyle, SceneTextStyle, SceneTransition, } from "./scene/types";
20
+ export { boxesEqual, contentHash, elementContentHash, MAX_SCENE_DEPTH, POINT_SHAPE_ARITY, POINT_SHAPE_TYPES, } from "./scene/types";
21
+ export { SHAPE_TYPES, sceneGeometry, geometryEqual, tweenAt, levelOpacity } from "../mirror/geometry";
22
+ export type { MirrorSceneElement, SceneGeometry } from "../mirror/geometry";
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY,EACV,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,UAAU,GACX,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAA;AACvC,YAAY,EAAC,eAAe,EAAE,eAAe,EAAC,MAAM,YAAY,CAAA;AAChE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,GACd,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAC,WAAW,EAAE,oBAAoB,EAAC,MAAM,WAAW,CAAA;AAC3D,YAAY,EAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAC,MAAM,WAAW,CAAA;AAE9E,OAAO,EAAC,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAC,MAAM,YAAY,CAAA;AACjF,YAAY,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAA;AAExC,YAAY,EACV,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,aAAa,EACb,cAAc,EACd,WAAW,EACX,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAA;AACnG,YAAY,EAAC,kBAAkB,EAAE,aAAa,EAAC,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @glassly/miniapp/display — the phone-side text and scene primitives a
3
+ * miniapp needs to lay out a frame the way the host measures it: the glasses'
4
+ * display profiles (glyph widths, line heights), pixel-accurate measurement
5
+ * and wrapping, pixel-art icons as scene images, and the scene element types
6
+ * the host's render pipeline consumes. Pure TypeScript with no host imports;
7
+ * the engine's scene pipeline (`processScene`) uses these same modules, so a
8
+ * miniapp that wraps text with them gets the rows the glasses will draw.
9
+ */
10
+ export { G1_PROFILE, G1_PROFILE_LEGACY, G1_HYPHEN_WIDTH_PX, G1_SPACE_WIDTH_PX, G2_PROFILE, G2_HYPHEN_WIDTH_PX, G2_SPACE_WIDTH_PX, Z100_PROFILE, Z100_HYPHEN_WIDTH_PX, Z100_SPACE_WIDTH_PX, NEX_PROFILE, NEX_HYPHEN_WIDTH_PX, NEX_SPACE_WIDTH_PX, } from "./profiles";
11
+ export { TextMeasurer } from "./measurer";
12
+ export { detectScript, isCJKCharacter, isKoreanCharacter, isUniformWidthScript, isUnsupportedScript, needsHyphenForBreak, SCRIPT_RANGES, } from "./measurer";
13
+ export { TextWrapper, DEFAULT_WRAP_OPTIONS } from "./wrapper";
14
+ export { pixelArtElement, pixelArtPng, pixelArtSize, pixelLevel } from "./pixelArt";
15
+ export { boxesEqual, contentHash, elementContentHash, MAX_SCENE_DEPTH, POINT_SHAPE_ARITY, POINT_SHAPE_TYPES, } from "./scene/types";
16
+ export { SHAPE_TYPES, sceneGeometry, geometryEqual, tweenAt, levelOpacity } from "../mirror/geometry";
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAA;AAEvC,OAAO,EACL,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,GACd,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAC,WAAW,EAAE,oBAAoB,EAAC,MAAM,WAAW,CAAA;AAG3D,OAAO,EAAC,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAC,MAAM,YAAY,CAAA;AAuBjF,OAAO,EACL,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,160 @@
1
+ import type { DisplayProfile, ScriptType } from "../profiles/types";
2
+ /**
3
+ * Character measurement result with detailed breakdown.
4
+ */
5
+ export interface CharMeasurement {
6
+ /** The character measured */
7
+ char: string;
8
+ /** Width in rendered pixels */
9
+ widthPx: number;
10
+ /** The script type of the character */
11
+ script: ScriptType;
12
+ /** Whether width came from glyph map (true) or fallback (false) */
13
+ fromGlyphMap: boolean;
14
+ }
15
+ /**
16
+ * Text measurement result with detailed breakdown.
17
+ */
18
+ export interface TextMeasurement {
19
+ /** The text measured */
20
+ text: string;
21
+ /** Total width in rendered pixels */
22
+ totalWidthPx: number;
23
+ /** Number of characters */
24
+ charCount: number;
25
+ /** Per-character measurements (optional, for debugging) */
26
+ chars?: CharMeasurement[];
27
+ }
28
+ /**
29
+ * Measures text width in pixels based on a DisplayProfile.
30
+ * All measurements are in actual rendered pixels, not abstract units.
31
+ *
32
+ * Key features:
33
+ * - Pixel-perfect measurement for mapped characters
34
+ * - Uniform-width handling for CJK, Korean, Cyrillic
35
+ * - Safe fallback for unmapped Latin characters
36
+ * - Caching for performance
37
+ */
38
+ export declare class TextMeasurer {
39
+ private readonly profile;
40
+ private readonly charCache;
41
+ constructor(profile: DisplayProfile);
42
+ /**
43
+ * Pre-compute rendered widths for all known glyphs.
44
+ */
45
+ private buildCharCache;
46
+ /**
47
+ * Measure the total pixel width of a text string.
48
+ *
49
+ * @param text - The text to measure
50
+ * @returns Width in rendered pixels
51
+ */
52
+ measureText(text: string): number;
53
+ /**
54
+ * Measure text with detailed breakdown of each character.
55
+ *
56
+ * @param text - The text to measure
57
+ * @returns Detailed measurement result
58
+ */
59
+ measureTextDetailed(text: string): TextMeasurement;
60
+ /**
61
+ * Measure a single character's pixel width.
62
+ *
63
+ * IMPORTANT: This is PIXEL-PERFECT measurement, not averaging!
64
+ * - Mapped characters: exact width from glyph map
65
+ * - Uniform scripts (CJK, Korean, Cyrillic): verified uniform width
66
+ * - Unmapped Latin: MAX width fallback (safe, never overflow)
67
+ *
68
+ * @param char - Single character to measure
69
+ * @returns Width in rendered pixels
70
+ */
71
+ measureChar(char: string): number;
72
+ /**
73
+ * Calculate character width (called when not in cache).
74
+ */
75
+ private calculateCharWidth;
76
+ /**
77
+ * Get the raw glyph width (before render formula).
78
+ * Returns undefined for unmapped characters.
79
+ *
80
+ * @param char - Single character
81
+ * @returns Glyph width in pixels, or undefined if not in glyph map
82
+ */
83
+ getGlyphWidth(char: string): number | undefined;
84
+ /**
85
+ * Check if text fits within a pixel width.
86
+ *
87
+ * @param text - Text to check
88
+ * @param maxWidthPx - Maximum width in pixels
89
+ * @returns true if text fits
90
+ */
91
+ fitsInWidth(text: string, maxWidthPx: number): boolean;
92
+ /**
93
+ * Find how many characters fit within a pixel width.
94
+ *
95
+ * @param text - Text to measure
96
+ * @param maxWidthPx - Maximum width in pixels
97
+ * @param startIndex - Starting index (default: 0)
98
+ * @returns Number of characters that fit
99
+ */
100
+ charsThatFit(text: string, maxWidthPx: number, startIndex?: number): number;
101
+ /**
102
+ * Find the pixel position of a character index in text.
103
+ *
104
+ * @param text - Text to measure
105
+ * @param index - Character index
106
+ * @returns Pixel offset from start of text
107
+ */
108
+ getPixelOffset(text: string, index: number): number;
109
+ /**
110
+ * Detect the script type of a character.
111
+ *
112
+ * @param char - Single character
113
+ * @returns Script type
114
+ */
115
+ detectScript(char: string): ScriptType;
116
+ /**
117
+ * Check if a character is from a uniform-width script.
118
+ *
119
+ * @param char - Single character
120
+ * @returns true if character is from CJK, Korean, or Cyrillic
121
+ */
122
+ isUniformWidth(char: string): boolean;
123
+ /**
124
+ * Get the display profile.
125
+ */
126
+ getProfile(): DisplayProfile;
127
+ /**
128
+ * Get the display width in pixels.
129
+ */
130
+ getDisplayWidthPx(): number;
131
+ /**
132
+ * Get the maximum number of lines.
133
+ */
134
+ getMaxLines(): number;
135
+ /**
136
+ * Get the maximum payload size in bytes.
137
+ */
138
+ getMaxPayloadBytes(): number;
139
+ /**
140
+ * Calculate the UTF-8 byte size of text.
141
+ *
142
+ * @param text - Text to measure
143
+ * @returns Byte size
144
+ */
145
+ getByteSize(text: string): number;
146
+ /**
147
+ * Get the width of a hyphen character in rendered pixels.
148
+ */
149
+ getHyphenWidth(): number;
150
+ /**
151
+ * Get the width of a space character in rendered pixels.
152
+ */
153
+ getSpaceWidth(): number;
154
+ /**
155
+ * Clear the character cache.
156
+ * Useful if profile metrics change at runtime.
157
+ */
158
+ clearCache(): void;
159
+ }
160
+ //# sourceMappingURL=TextMeasurer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextMeasurer.d.ts","sourceRoot":"","sources":["../../../src/display/measurer/TextMeasurer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAE,UAAU,EAAC,MAAM,mBAAmB,CAAA;AAGjE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,uCAAuC;IACvC,MAAM,EAAE,UAAU,CAAA;IAClB,mEAAmE;IACnE,YAAY,EAAE,OAAO,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAA;IACpB,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;CAC1B;AAED;;;;;;;;;GASG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;gBAE/C,OAAO,EAAE,cAAc;IAMnC;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAYjC;;;;;OAKG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;IAoClD;;;;;;;;;;OAUG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAoBjC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA+B1B;;;;;;OAMG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI/C;;;;;;OAMG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IAItD;;;;;;;OAOG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAE,MAAU,GAAG,MAAM;IAyB9E;;;;;;OAMG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAenD;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAItC;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIrC;;OAEG;IACH,UAAU,IAAI,cAAc;IAI5B;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAI5B;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIjC;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;;OAGG;IACH,UAAU,IAAI,IAAI;CAInB"}
@@ -0,0 +1,272 @@
1
+ import { detectScript, isUniformWidthScript } from "./script-detection";
2
+ /**
3
+ * Measures text width in pixels based on a DisplayProfile.
4
+ * All measurements are in actual rendered pixels, not abstract units.
5
+ *
6
+ * Key features:
7
+ * - Pixel-perfect measurement for mapped characters
8
+ * - Uniform-width handling for CJK, Korean, Cyrillic
9
+ * - Safe fallback for unmapped Latin characters
10
+ * - Caching for performance
11
+ */
12
+ export class TextMeasurer {
13
+ constructor(profile) {
14
+ this.charCache = new Map();
15
+ this.profile = profile;
16
+ // Pre-populate cache with known glyphs
17
+ this.buildCharCache();
18
+ }
19
+ /**
20
+ * Pre-compute rendered widths for all known glyphs.
21
+ */
22
+ buildCharCache() {
23
+ const { glyphWidths, renderFormula } = this.profile.fontMetrics;
24
+ for (const [char, glyphWidth] of glyphWidths.entries()) {
25
+ const renderedWidth = renderFormula(glyphWidth);
26
+ this.charCache.set(char, renderedWidth);
27
+ }
28
+ }
29
+ /**
30
+ * Measure the total pixel width of a text string.
31
+ *
32
+ * @param text - The text to measure
33
+ * @returns Width in rendered pixels
34
+ */
35
+ measureText(text) {
36
+ if (!text || text.length === 0) {
37
+ return 0;
38
+ }
39
+ let totalWidth = 0;
40
+ for (const char of text) {
41
+ totalWidth += this.measureChar(char);
42
+ }
43
+ return totalWidth;
44
+ }
45
+ /**
46
+ * Measure text with detailed breakdown of each character.
47
+ *
48
+ * @param text - The text to measure
49
+ * @returns Detailed measurement result
50
+ */
51
+ measureTextDetailed(text) {
52
+ if (!text || text.length === 0) {
53
+ return {
54
+ text: "",
55
+ totalWidthPx: 0,
56
+ charCount: 0,
57
+ chars: [],
58
+ };
59
+ }
60
+ const chars = [];
61
+ let totalWidth = 0;
62
+ for (const char of text) {
63
+ const script = detectScript(char);
64
+ const widthPx = this.measureChar(char);
65
+ const fromGlyphMap = this.profile.fontMetrics.glyphWidths.has(char);
66
+ chars.push({
67
+ char,
68
+ widthPx,
69
+ script,
70
+ fromGlyphMap,
71
+ });
72
+ totalWidth += widthPx;
73
+ }
74
+ return {
75
+ text,
76
+ totalWidthPx: totalWidth,
77
+ charCount: chars.length,
78
+ chars,
79
+ };
80
+ }
81
+ /**
82
+ * Measure a single character's pixel width.
83
+ *
84
+ * IMPORTANT: This is PIXEL-PERFECT measurement, not averaging!
85
+ * - Mapped characters: exact width from glyph map
86
+ * - Uniform scripts (CJK, Korean, Cyrillic): verified uniform width
87
+ * - Unmapped Latin: MAX width fallback (safe, never overflow)
88
+ *
89
+ * @param char - Single character to measure
90
+ * @returns Width in rendered pixels
91
+ */
92
+ measureChar(char) {
93
+ if (!char || char.length === 0) {
94
+ return 0;
95
+ }
96
+ // Check cache first (includes pre-computed glyph map entries)
97
+ const cached = this.charCache.get(char);
98
+ if (cached !== undefined) {
99
+ return cached;
100
+ }
101
+ // Calculate width based on script type
102
+ const width = this.calculateCharWidth(char);
103
+ // Cache for future lookups
104
+ this.charCache.set(char, width);
105
+ return width;
106
+ }
107
+ /**
108
+ * Calculate character width (called when not in cache).
109
+ */
110
+ calculateCharWidth(char) {
111
+ const { fontMetrics } = this.profile;
112
+ const { uniformScripts, fallback, renderFormula, glyphWidths } = fontMetrics;
113
+ // 1. Check explicit glyph map (pixel-perfect for Latin)
114
+ const glyphWidth = glyphWidths.get(char);
115
+ if (glyphWidth !== undefined) {
116
+ return renderFormula(glyphWidth);
117
+ }
118
+ // 2. Uniform-width scripts (verified monospace - NOT averages!)
119
+ const script = detectScript(char);
120
+ switch (script) {
121
+ case "cjk":
122
+ return uniformScripts.cjk; // ALL CJK chars are exactly this width
123
+ case "hiragana":
124
+ return uniformScripts.hiragana; // ALL Hiragana chars are exactly this width
125
+ case "katakana":
126
+ return uniformScripts.katakana; // ALL Katakana chars are exactly this width
127
+ case "korean":
128
+ return uniformScripts.korean; // ALL Korean chars are exactly this width
129
+ case "cyrillic":
130
+ return uniformScripts.cyrillic; // ALL Cyrillic chars are exactly this width
131
+ }
132
+ // 3. Unmapped Latin or unknown: use MAX width (safe fallback)
133
+ // This guarantees we NEVER overflow - worst case is slight under-utilization
134
+ return fallback.latinMaxWidth;
135
+ }
136
+ /**
137
+ * Get the raw glyph width (before render formula).
138
+ * Returns undefined for unmapped characters.
139
+ *
140
+ * @param char - Single character
141
+ * @returns Glyph width in pixels, or undefined if not in glyph map
142
+ */
143
+ getGlyphWidth(char) {
144
+ return this.profile.fontMetrics.glyphWidths.get(char);
145
+ }
146
+ /**
147
+ * Check if text fits within a pixel width.
148
+ *
149
+ * @param text - Text to check
150
+ * @param maxWidthPx - Maximum width in pixels
151
+ * @returns true if text fits
152
+ */
153
+ fitsInWidth(text, maxWidthPx) {
154
+ return this.measureText(text) <= maxWidthPx;
155
+ }
156
+ /**
157
+ * Find how many characters fit within a pixel width.
158
+ *
159
+ * @param text - Text to measure
160
+ * @param maxWidthPx - Maximum width in pixels
161
+ * @param startIndex - Starting index (default: 0)
162
+ * @returns Number of characters that fit
163
+ */
164
+ charsThatFit(text, maxWidthPx, startIndex = 0) {
165
+ if (!text || startIndex >= text.length) {
166
+ return 0;
167
+ }
168
+ let currentWidth = 0;
169
+ let count = 0;
170
+ // Use Array.from to handle surrogate pairs correctly
171
+ const chars = Array.from(text).slice(startIndex);
172
+ for (const char of chars) {
173
+ const charWidth = this.measureChar(char);
174
+ if (currentWidth + charWidth > maxWidthPx) {
175
+ break;
176
+ }
177
+ currentWidth += charWidth;
178
+ count++;
179
+ }
180
+ return count;
181
+ }
182
+ /**
183
+ * Find the pixel position of a character index in text.
184
+ *
185
+ * @param text - Text to measure
186
+ * @param index - Character index
187
+ * @returns Pixel offset from start of text
188
+ */
189
+ getPixelOffset(text, index) {
190
+ if (!text || index <= 0) {
191
+ return 0;
192
+ }
193
+ const chars = Array.from(text).slice(0, index);
194
+ let offset = 0;
195
+ for (const char of chars) {
196
+ offset += this.measureChar(char);
197
+ }
198
+ return offset;
199
+ }
200
+ /**
201
+ * Detect the script type of a character.
202
+ *
203
+ * @param char - Single character
204
+ * @returns Script type
205
+ */
206
+ detectScript(char) {
207
+ return detectScript(char);
208
+ }
209
+ /**
210
+ * Check if a character is from a uniform-width script.
211
+ *
212
+ * @param char - Single character
213
+ * @returns true if character is from CJK, Korean, or Cyrillic
214
+ */
215
+ isUniformWidth(char) {
216
+ return isUniformWidthScript(char);
217
+ }
218
+ /**
219
+ * Get the display profile.
220
+ */
221
+ getProfile() {
222
+ return this.profile;
223
+ }
224
+ /**
225
+ * Get the display width in pixels.
226
+ */
227
+ getDisplayWidthPx() {
228
+ return this.profile.displayWidthPx;
229
+ }
230
+ /**
231
+ * Get the maximum number of lines.
232
+ */
233
+ getMaxLines() {
234
+ return this.profile.maxLines;
235
+ }
236
+ /**
237
+ * Get the maximum payload size in bytes.
238
+ */
239
+ getMaxPayloadBytes() {
240
+ return this.profile.maxPayloadBytes;
241
+ }
242
+ /**
243
+ * Calculate the UTF-8 byte size of text.
244
+ *
245
+ * @param text - Text to measure
246
+ * @returns Byte size
247
+ */
248
+ getByteSize(text) {
249
+ return new TextEncoder().encode(text).length;
250
+ }
251
+ /**
252
+ * Get the width of a hyphen character in rendered pixels.
253
+ */
254
+ getHyphenWidth() {
255
+ return this.measureChar("-");
256
+ }
257
+ /**
258
+ * Get the width of a space character in rendered pixels.
259
+ */
260
+ getSpaceWidth() {
261
+ return this.measureChar(" ");
262
+ }
263
+ /**
264
+ * Clear the character cache.
265
+ * Useful if profile metrics change at runtime.
266
+ */
267
+ clearCache() {
268
+ this.charCache.clear();
269
+ this.buildCharCache();
270
+ }
271
+ }
272
+ //# sourceMappingURL=TextMeasurer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextMeasurer.js","sourceRoot":"","sources":["../../../src/display/measurer/TextMeasurer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Text Measurer Module
3
+ *
4
+ * Provides pixel-accurate text measurement based on display profiles.
5
+ * All measurements are in actual rendered pixels, not abstract units.
6
+ */
7
+ export { TextMeasurer } from "./TextMeasurer";
8
+ export type { CharMeasurement, TextMeasurement } from "./TextMeasurer";
9
+ export { detectScript, isCJKCharacter, isKoreanCharacter, isUniformWidthScript, isUnsupportedScript, needsHyphenForBreak, SCRIPT_RANGES, } from "./script-detection";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/display/measurer/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAA;AAC3C,YAAY,EAAC,eAAe,EAAE,eAAe,EAAC,MAAM,gBAAgB,CAAA;AAGpE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,GACd,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Text Measurer Module
3
+ *
4
+ * Provides pixel-accurate text measurement based on display profiles.
5
+ * All measurements are in actual rendered pixels, not abstract units.
6
+ */
7
+ // Main class
8
+ export { TextMeasurer } from "./TextMeasurer";
9
+ // Script detection utilities
10
+ export { detectScript, isCJKCharacter, isKoreanCharacter, isUniformWidthScript, isUnsupportedScript, needsHyphenForBreak, SCRIPT_RANGES, } from "./script-detection";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/display/measurer/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,aAAa;AACb,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAA;AAG3C,6BAA6B;AAC7B,OAAO,EACL,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,GACd,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,53 @@
1
+ import type { ScriptType } from "../profiles/types";
2
+ /**
3
+ * Unicode ranges for script detection.
4
+ * Used to classify characters for proper width measurement.
5
+ */
6
+ export declare const SCRIPT_RANGES: {
7
+ readonly cjk: readonly [readonly [19968, 40959], readonly [13312, 19903], readonly [131072, 173791], readonly [173824, 177983], readonly [177984, 178207], readonly [63744, 64255]];
8
+ readonly hiragana: readonly [readonly [12352, 12447]];
9
+ readonly katakana: readonly [readonly [12448, 12543], readonly [12784, 12799]];
10
+ readonly korean: readonly [readonly [44032, 55215], readonly [4352, 4607], readonly [12592, 12687], readonly [43360, 43391], readonly [55216, 55295]];
11
+ readonly cyrillic: readonly [readonly [1024, 1279], readonly [1280, 1327]];
12
+ readonly numbers: readonly [readonly [48, 57]];
13
+ readonly punctuation: readonly [readonly [32, 47], readonly [58, 64], readonly [91, 96], readonly [123, 126]];
14
+ readonly arabic: readonly [readonly [1536, 1791]];
15
+ readonly hebrew: readonly [readonly [1424, 1535]];
16
+ readonly thai: readonly [readonly [3584, 3711]];
17
+ readonly emoji: readonly [readonly [128512, 128591], readonly [127744, 128511], readonly [128640, 128767], readonly [127456, 127487], readonly [9728, 9983], readonly [9984, 10175], readonly [65024, 65039], readonly [129280, 129535]];
18
+ };
19
+ /**
20
+ * Detect the script type of a single character.
21
+ *
22
+ * @param char - Single character to classify
23
+ * @returns The script type of the character
24
+ */
25
+ export declare function detectScript(char: string): ScriptType;
26
+ /**
27
+ * Check if a character is a CJK character (Chinese, Japanese Kanji).
28
+ * CJK characters can break anywhere without needing a hyphen.
29
+ */
30
+ export declare function isCJKCharacter(char: string): boolean;
31
+ /**
32
+ * Check if a character is Korean Hangul.
33
+ */
34
+ export declare function isKoreanCharacter(char: string): boolean;
35
+ /**
36
+ * Check if a character is from a uniform-width script.
37
+ * These scripts render all characters at the same width.
38
+ */
39
+ export declare function isUniformWidthScript(char: string): boolean;
40
+ /**
41
+ * Check if a character is from an unsupported script.
42
+ * These characters may not render correctly on the glasses.
43
+ */
44
+ export declare function isUnsupportedScript(char: string): boolean;
45
+ /**
46
+ * Check if breaking between two characters requires a hyphen.
47
+ * Returns false for:
48
+ * - Breaking after CJK characters (can break anywhere)
49
+ * - Breaking before or after spaces
50
+ * - Breaking after punctuation
51
+ */
52
+ export declare function needsHyphenForBreak(charBefore: string, charAfter: string): boolean;
53
+ //# sourceMappingURL=script-detection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script-detection.d.ts","sourceRoot":"","sources":["../../../src/display/measurer/script-detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAA;AAEjD;;;GAGG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;CA4DhB,CAAA;AAcV;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CA0DrD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGpD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAK1D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CA6BlF"}