ranger-compiler 3.5.0 → 3.5.2

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 (338) hide show
  1. package/CHANGELOG.md +1160 -19
  2. package/LICENSE +3 -1
  3. package/README.md +124 -29
  4. package/dist/Lang.rgr +1188 -290
  5. package/dist/api.d.ts +2343 -879
  6. package/dist/api.js +79924 -56922
  7. package/dist/lib/JSON.rgr +102 -91
  8. package/dist/lib/Shell.rgr +4 -4
  9. package/dist/lib/apple/AppleToolchain.rgr +4 -4
  10. package/dist/lib/apple/README.md +5 -4
  11. package/dist/lib/apple/apple_test.rgr +1 -1
  12. package/dist/lib/core/README.md +1 -1
  13. package/dist/lib/evg/EVG.rgr +12 -0
  14. package/dist/lib/evg/EVGA11yFromTree.rgr +302 -0
  15. package/dist/lib/evg/EVGA11yTree.rgr +894 -0
  16. package/dist/lib/evg/EVGBox.rgr +267 -0
  17. package/dist/lib/evg/EVGBoxShorthandTest.rgr +220 -0
  18. package/dist/lib/evg/EVGCodepoint.rgr +316 -0
  19. package/dist/lib/evg/EVGColor.rgr +700 -0
  20. package/dist/lib/evg/EVGCommands.rgr +177 -0
  21. package/dist/lib/evg/EVGComponent.rgr +331 -0
  22. package/dist/lib/evg/EVGComponentTest.rgr +387 -0
  23. package/dist/lib/evg/EVGConnector.rgr +541 -0
  24. package/dist/lib/evg/EVGConnectorTest.rgr +306 -0
  25. package/dist/lib/evg/EVGDisplayList.rgr +4186 -0
  26. package/dist/lib/evg/EVGEasing.rgr +370 -0
  27. package/dist/lib/evg/EVGEffectTest.rgr +253 -0
  28. package/dist/lib/evg/EVGElement.rgr +4914 -0
  29. package/dist/lib/evg/EVGFixedTest.rgr +289 -0
  30. package/dist/lib/evg/EVGFlexRulesTest.rgr +317 -0
  31. package/dist/lib/evg/EVGFlexWrapTest.rgr +246 -0
  32. package/dist/lib/evg/EVGFling.rgr +244 -0
  33. package/dist/lib/evg/EVGFocus.rgr +400 -0
  34. package/dist/lib/evg/EVGFocusTest.rgr +399 -0
  35. package/dist/lib/evg/EVGGradient.rgr +322 -0
  36. package/dist/lib/evg/EVGGrapheme.rgr +190 -0
  37. package/dist/lib/evg/EVGGrid.rgr +975 -0
  38. package/dist/lib/evg/EVGHitTest.rgr +208 -0
  39. package/dist/lib/evg/EVGHoles.rgr +294 -0
  40. package/dist/lib/evg/EVGHostMeasurerTest.rgr +281 -0
  41. package/dist/lib/evg/EVGHostTextMeasurer.rgr +331 -0
  42. package/dist/lib/evg/EVGHostTree.rgr +834 -0
  43. package/dist/lib/evg/EVGHostTreeTest.rgr +447 -0
  44. package/dist/lib/evg/EVGImageDecode.rgr +117 -0
  45. package/dist/lib/evg/EVGImageMeasurer.rgr +86 -0
  46. package/dist/lib/evg/EVGInspect.rgr +883 -0
  47. package/dist/lib/evg/EVGInvalidateTest.rgr +432 -0
  48. package/dist/lib/evg/EVGJsonTest.rgr +535 -0
  49. package/dist/lib/evg/EVGLayout.rgr +4220 -0
  50. package/dist/lib/evg/EVGMeasure.rgr +1267 -0
  51. package/dist/lib/evg/EVGOverlayTest.rgr +626 -0
  52. package/dist/lib/evg/EVGPatch.rgr +1721 -0
  53. package/dist/lib/evg/EVGPatchTest.rgr +692 -0
  54. package/dist/lib/evg/EVGPopoverTest.rgr +395 -0
  55. package/dist/lib/evg/EVGReconcile.rgr +226 -0
  56. package/dist/lib/evg/EVGReconcileTest.rgr +421 -0
  57. package/dist/lib/evg/EVGReject.rgr +126 -0
  58. package/dist/lib/evg/EVGRelayoutTest.rgr +375 -0
  59. package/dist/lib/evg/EVGRtlLayoutTest.rgr +319 -0
  60. package/dist/lib/evg/EVGRuler.rgr +232 -0
  61. package/dist/lib/evg/EVGRulerTest.rgr +172 -0
  62. package/dist/lib/evg/EVGSelectChrome.rgr +178 -0
  63. package/dist/lib/evg/EVGStyleCacheTest.rgr +419 -0
  64. package/dist/lib/evg/EVGStyleSheet.rgr +2148 -0
  65. package/dist/lib/evg/EVGStyleStateTest.rgr +407 -0
  66. package/dist/lib/evg/EVGStyleVarTest.rgr +471 -0
  67. package/dist/lib/evg/EVGText.rgr +105 -0
  68. package/dist/lib/evg/EVGTextEngine.rgr +536 -0
  69. package/dist/lib/evg/EVGTextMeasurer.rgr +720 -0
  70. package/dist/lib/evg/EVGTimingTest.rgr +1417 -0
  71. package/dist/lib/evg/EVGToolbar.rgr +1369 -0
  72. package/dist/lib/evg/EVGTransition.rgr +728 -0
  73. package/dist/lib/evg/EVGTreeJson.rgr +721 -0
  74. package/dist/lib/evg/EVGUnit.rgr +554 -0
  75. package/dist/lib/evg/EVGViewportUnitTest.rgr +236 -0
  76. package/dist/lib/evg/EvgApp.rgr +189 -0
  77. package/dist/lib/evg/EvgBitmapTracer.rgr +4277 -0
  78. package/dist/lib/evg/EvgBitmapTracerTest.rgr +2119 -0
  79. package/dist/lib/evg/EvgHost.rgr +451 -0
  80. package/dist/lib/evg/EvgTest.rgr +91 -0
  81. package/dist/lib/evg/EvgTraceColor.rgr +236 -0
  82. package/dist/lib/evg/EvgTraceCurve.rgr +648 -0
  83. package/dist/lib/evg/EvgTraceFit.rgr +767 -0
  84. package/dist/lib/evg/EvgTracePath.rgr +435 -0
  85. package/dist/lib/evg/EvgTraceTypes.rgr +559 -0
  86. package/dist/lib/evg/EvgViewport.rgr +313 -0
  87. package/dist/lib/evg/FxDemoDoc.rgr +185 -0
  88. package/dist/lib/evg/HOSTS.md +227 -0
  89. package/dist/lib/evg/ISSUES.md +835 -0
  90. package/dist/lib/evg/PLAN_ACCESSIBILITY.md +650 -0
  91. package/dist/lib/evg/PLAN_CSS_LAYOUT_AND_FONTS.md +1124 -0
  92. package/dist/lib/evg/PLAN_EFFECTS.md +431 -0
  93. package/dist/lib/evg/PLAN_EVG.md +518 -0
  94. package/dist/lib/evg/PLAN_EVG_RENDERER.md +1674 -0
  95. package/dist/lib/evg/PLAN_INSPECTOR.md +788 -0
  96. package/dist/lib/evg/PLAN_LINKS_AND_FORMS.md +157 -0
  97. package/dist/lib/evg/PLAN_NATIVE_HOSTS.md +671 -0
  98. package/dist/lib/evg/PLAN_VECTOR_IR.md +664 -0
  99. package/dist/lib/evg/PLAN_VIEW_TRANSFORM.md +322 -0
  100. package/dist/lib/evg/PathBuilder.rgr +333 -0
  101. package/dist/lib/evg/README.md +1236 -0
  102. package/dist/lib/evg/SPEC.md +1252 -0
  103. package/dist/lib/evg/SVGPathParser.rgr +1199 -0
  104. package/dist/lib/evg/SvgParser.rgr +1736 -0
  105. package/dist/lib/evg/TODO_EVG_RENDERER.md +595 -0
  106. package/dist/lib/evg/VectorShapes.rgr +331 -0
  107. package/dist/lib/evg/VectorStroke.rgr +107 -0
  108. package/dist/lib/evg/VectorViewBox.rgr +380 -0
  109. package/dist/lib/evg/agent/README.md +290 -0
  110. package/dist/lib/evg/agent/evg_agent.rgr +899 -0
  111. package/dist/lib/evg/agent/fixtures/broken.evg.json +7 -0
  112. package/dist/lib/evg/agent/fixtures/card.evg.json +9 -0
  113. package/dist/lib/evg/agent/fixtures/connector.css +63 -0
  114. package/dist/lib/evg/agent/fixtures/connector.evg.json +14 -0
  115. package/dist/lib/evg/agent/fixtures/drawn.evg.json +129 -0
  116. package/dist/lib/evg/agent/fixtures/gradient.evg.json +4 -0
  117. package/dist/lib/evg/agent/fixtures/popover.css +99 -0
  118. package/dist/lib/evg/agent/fixtures/popover.evg.json +30 -0
  119. package/dist/lib/evg/agent/roundtrip.sh +74 -0
  120. package/dist/lib/evg/agent/smoke.sh +230 -0
  121. package/dist/lib/evg/android/README.md +97 -0
  122. package/dist/lib/evg/android/androidstubs/AndroidStubs.kt +175 -0
  123. package/dist/lib/evg/android/androidstubs/Annotation.kt +10 -0
  124. package/dist/lib/evg/android/androidstubs/App.kt +30 -0
  125. package/dist/lib/evg/android/androidstubs/Content.kt +41 -0
  126. package/dist/lib/evg/android/androidstubs/ContentRes.kt +12 -0
  127. package/dist/lib/evg/android/androidstubs/InputMethod.kt +46 -0
  128. package/dist/lib/evg/android/androidstubs/Net.kt +6 -0
  129. package/dist/lib/evg/android/androidstubs/Os.kt +30 -0
  130. package/dist/lib/evg/android/androidstubs/Util.kt +15 -0
  131. package/dist/lib/evg/android/androidstubs/View.kt +113 -0
  132. package/dist/lib/evg/android/androidstubs/Widget.kt +16 -0
  133. package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidEvgSurface.kt +323 -0
  134. package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidTextMeasurer.kt +56 -0
  135. package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/RippleEffect.kt +262 -0
  136. package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtEvgSurface.kt +238 -0
  137. package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtTextMeasurer.kt +85 -0
  138. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgEngineThread.kt +115 -0
  139. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgPainter.kt +231 -0
  140. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgSurface.kt +117 -0
  141. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/RecordingSurface.kt +94 -0
  142. package/dist/lib/evg/apple/README.md +128 -0
  143. package/dist/lib/evg/apple/Sources/CoreGraphicsEvgSurface.swift +329 -0
  144. package/dist/lib/evg/apple/Sources/CoreTextMeasurer.swift +70 -0
  145. package/dist/lib/evg/apple/Sources/EvgEngineQueue.swift +105 -0
  146. package/dist/lib/evg/apple/Sources/EvgPainter.swift +225 -0
  147. package/dist/lib/evg/apple/Sources/EvgSurface.swift +163 -0
  148. package/dist/lib/evg/apple/Sources/RecordingSurface.swift +110 -0
  149. package/dist/lib/evg/bench/EvgLayoutBench.rgr +34 -0
  150. package/dist/lib/evg/bench/README.md +64 -0
  151. package/dist/lib/evg/bench/layout-bench.mjs +316 -0
  152. package/dist/lib/evg/bench/layout-cases.mjs +510 -0
  153. package/dist/lib/evg/bench/layout-conformance.mjs +254 -0
  154. package/dist/lib/evg/bin/.gitignore +17 -0
  155. package/dist/lib/evg/evg_test.rgr +313 -0
  156. package/dist/lib/evg/gl/README.md +198 -0
  157. package/dist/lib/evg/gl/a11y-paint-check.mjs +73 -0
  158. package/dist/lib/evg/gl/blur-check.mjs +399 -0
  159. package/dist/lib/evg/gl/boxmodel.json +1 -0
  160. package/dist/lib/evg/gl/demo.html +46 -0
  161. package/dist/lib/evg/gl/effect-presets.css +285 -0
  162. package/dist/lib/evg/gl/effect-presets.js +63 -0
  163. package/dist/lib/evg/gl/effect-shots.mjs +135 -0
  164. package/dist/lib/evg/gl/evg-a11y.js +566 -0
  165. package/dist/lib/evg/gl/evg-binary.js +160 -0
  166. package/dist/lib/evg/gl/evg-engine.js +296 -0
  167. package/dist/lib/evg/gl/evg-fx.js +237 -0
  168. package/dist/lib/evg/gl/evg-gestures.js +209 -0
  169. package/dist/lib/evg/gl/evg-list.js +167 -0
  170. package/dist/lib/evg/gl/evg-measure.js +186 -0
  171. package/dist/lib/evg/gl/evg-textinput.js +303 -0
  172. package/dist/lib/evg/gl/evg-view.js +144 -0
  173. package/dist/lib/evg/gl/evg-webgl.js +3942 -0
  174. package/dist/lib/evg/gl/fx-check.mjs +998 -0
  175. package/dist/lib/evg/gl/fx-demo.html +166 -0
  176. package/dist/lib/evg/gl/fx-demo.js +2 -0
  177. package/dist/lib/evg/gl/fx-serve.mjs +47 -0
  178. package/dist/lib/evg/gl/gestures-check.mjs +189 -0
  179. package/dist/lib/evg/gl/list-binary-check.mjs +152 -0
  180. package/dist/lib/evg/gl/measure-check.mjs +135 -0
  181. package/dist/lib/evg/gl/rotation-check.mjs +207 -0
  182. package/dist/lib/evg/gl/shift-check.mjs +113 -0
  183. package/dist/lib/evg/gl/stroke-check.mjs +168 -0
  184. package/dist/lib/evg/gl/text-snap-check.mjs +139 -0
  185. package/dist/lib/evg/gl/view-check.mjs +343 -0
  186. package/dist/lib/evg/gl/view-policy-check.mjs +184 -0
  187. package/dist/lib/evg/html/evg-dom.js +318 -0
  188. package/dist/lib/evg/html/evg-html.js +600 -0
  189. package/dist/lib/evg/inspect/README.md +415 -0
  190. package/dist/lib/evg/inspect/browser-smoke.mjs +115 -0
  191. package/dist/lib/evg/inspect/evg-inspect.js +947 -0
  192. package/dist/lib/evg/inspect/shots/css.png +0 -0
  193. package/dist/lib/evg/inspect/shots/dashboard.png +0 -0
  194. package/dist/lib/evg/inspect/shots/pptx-slide.png +0 -0
  195. package/dist/lib/evg/inspect/shots/state.png +0 -0
  196. package/dist/lib/evg/inspect/shots.mjs +226 -0
  197. package/dist/lib/evg/oracle/css-blur.json +576 -0
  198. package/dist/lib/evg/oracle/css-box.json +157 -0
  199. package/dist/lib/evg/oracle/css-timing.json +709 -0
  200. package/dist/lib/evg/oracle/css_blur_oracle.mjs +529 -0
  201. package/dist/lib/evg/oracle/css_box_oracle.mjs +106 -0
  202. package/dist/lib/evg/oracle/css_timing_oracle.mjs +389 -0
  203. package/dist/lib/evg/original/EVGColor.clj +310 -0
  204. package/dist/lib/evg/original/EVGColorContext.rgr +178 -0
  205. package/dist/lib/evg/original/SVGPath.rgr +627 -0
  206. package/dist/lib/evg/original/Vec2.crgr +103 -0
  207. package/dist/lib/evg/ranger.json +9 -0
  208. package/dist/lib/evg/showcase/README.md +246 -0
  209. package/dist/lib/evg/showcase/assets/emblem.svg +30 -0
  210. package/dist/lib/evg/showcase/assets/rosette.svg +22 -0
  211. package/dist/lib/evg/showcase/build.mjs +651 -0
  212. package/dist/lib/evg/showcase/pages/album.tsx +30 -0
  213. package/dist/lib/evg/showcase/pages/boxmodel.tsx +37 -0
  214. package/dist/lib/evg/showcase/pages/cards.tsx +41 -0
  215. package/dist/lib/evg/showcase/pages/chart_api.tsx +170 -0
  216. package/dist/lib/evg/showcase/pages/charts.tsx +219 -0
  217. package/dist/lib/evg/showcase/pages/drawing.tsx +160 -0
  218. package/dist/lib/evg/showcase/pages/emoji.tsx +91 -0
  219. package/dist/lib/evg/showcase/pages/flex.tsx +46 -0
  220. package/dist/lib/evg/showcase/pages/more.tsx +332 -0
  221. package/dist/lib/evg/showcase/pages/plots.tsx +262 -0
  222. package/dist/lib/evg/showcase/pages/svg.tsx +63 -0
  223. package/dist/lib/evg/showcase/pages/tables.tsx +209 -0
  224. package/dist/lib/evg/showcase/pages/typography.tsx +43 -0
  225. package/dist/lib/evg/showcase/pages/units.tsx +35 -0
  226. package/dist/lib/evg/showcase/pages/variants.tsx +233 -0
  227. package/dist/lib/evg/showcase/pages/vector.tsx +75 -0
  228. package/dist/lib/evg/showcase/pages/views.tsx +223 -0
  229. package/dist/lib/evg/showcase/tests/chart_api_smoke.mjs +339 -0
  230. package/dist/lib/evg/showcase/tests/gl_smoke.mjs +125 -0
  231. package/dist/lib/evg/showcase/themes/chart_api-default.css +15 -0
  232. package/dist/lib/evg/showcase/themes/charts-default.css +29 -0
  233. package/dist/lib/evg/showcase/themes/drawing-default.css +35 -0
  234. package/dist/lib/evg/showcase/themes/more-default.css +128 -0
  235. package/dist/lib/evg/showcase/themes/plots-default.css +18 -0
  236. package/dist/lib/evg/showcase/themes/showcase.css +508 -0
  237. package/dist/lib/evg/showcase/themes/tables-default.css +123 -0
  238. package/dist/lib/evg/showcase/themes/variants-default.css +15 -0
  239. package/dist/lib/evg/showcase/themes/views-default.css +15 -0
  240. package/dist/lib/evg/tools/bench_vs_potrace.mjs +290 -0
  241. package/dist/lib/evg/tools/evg_image_tool.rgr +488 -0
  242. package/dist/lib/evg/tools/evg_trace_bench.rgr +114 -0
  243. package/dist/lib/evg/tools/evg_trace_cli.rgr +662 -0
  244. package/dist/lib/evg/tools/evg_trace_cpp_bench.rgr +83 -0
  245. package/dist/lib/evg/tools/run_trace_bench.sh +74 -0
  246. package/dist/lib/evg/tools/run_trace_cli_smoke.sh +128 -0
  247. package/dist/lib/evg/web/responsive/EvgResponsiveCheck.rgr +271 -0
  248. package/dist/lib/evg/web/responsive/EvgResponsiveDemo.rgr +531 -0
  249. package/dist/lib/evg/web/responsive/README.md +97 -0
  250. package/dist/lib/evg/web/responsive/build.mjs +90 -0
  251. package/dist/lib/evg/web/responsive/dom-check.mjs +169 -0
  252. package/dist/lib/evg/web/responsive/index.html +177 -0
  253. package/dist/lib/evg/web/responsive/smoke.mjs +221 -0
  254. package/dist/lib/evg/web/tools/assets-client.mjs +95 -0
  255. package/dist/lib/evg/web/tools/boot-bench.mjs +189 -0
  256. package/dist/lib/evg/web/tools/inline-assets.mjs +119 -0
  257. package/dist/lib/evg/web/tools/minify.mjs +60 -0
  258. package/dist/lib/evg/web/tracer/build.mjs +87 -0
  259. package/dist/lib/evg/web/tracer/index.html +2805 -0
  260. package/dist/lib/evg/web/tracer/sample.png +0 -0
  261. package/dist/lib/evg/web/tracer/smoke.mjs +1162 -0
  262. package/dist/lib/evgr/Cargo.lock +21 -0
  263. package/dist/lib/evgr/Cargo.toml +19 -0
  264. package/dist/lib/evgr/README.md +140 -0
  265. package/dist/lib/evgr/bench/NativeBench.rgr +246 -0
  266. package/dist/lib/evgr/bench/compare.mjs +252 -0
  267. package/dist/lib/evgr/bench/speed.mjs +277 -0
  268. package/dist/lib/evgr/bin/.gitignore +3 -0
  269. package/dist/lib/evgr/src/bin/bench.rs +106 -0
  270. package/dist/lib/evgr/src/bin/smoke.rs +13 -0
  271. package/dist/lib/evgr/src/grid.rs +730 -0
  272. package/dist/lib/evgr/src/lib.rs +1003 -0
  273. package/dist/lib/evgr/src/style.rs +468 -0
  274. package/dist/lib/evgr/src/text.rs +83 -0
  275. package/dist/lib/image/BitReader.rgr +171 -0
  276. package/dist/lib/image/Buffer.rgr +173 -0
  277. package/dist/lib/image/DCT.rgr +283 -0
  278. package/dist/lib/image/Deflate.rgr +339 -0
  279. package/dist/lib/image/HuffmanDecoder.rgr +181 -0
  280. package/dist/lib/image/ImageBuffer.rgr +706 -0
  281. package/dist/lib/image/JPEGDecoder.rgr +808 -0
  282. package/dist/lib/image/PNGDecoder.rgr +544 -0
  283. package/dist/lib/image/PNGEncoder.rgr +388 -0
  284. package/dist/lib/image/PPMImage.rgr +224 -0
  285. package/dist/lib/image/ProgressiveJPEGDecoder.rgr +1154 -0
  286. package/dist/lib/image/README.md +33 -0
  287. package/dist/lib/image/RasterBuffer.rgr +294 -0
  288. package/dist/lib/image/VP8BoolDecoder.rgr +163 -0
  289. package/dist/lib/image/WebPDecoder.rgr +433 -0
  290. package/dist/lib/image/WebPLossless.rgr +1035 -0
  291. package/dist/lib/image/WebPLossy.rgr +1929 -0
  292. package/dist/lib/image/ranger.json +9 -0
  293. package/dist/lib/image/testdata/webp/anim_2f_24x16.webp +0 -0
  294. package/dist/lib/image/testdata/webp/fixtures.txt +33 -0
  295. package/dist/lib/image/testdata/webp/gen_fixtures.py +261 -0
  296. package/dist/lib/image/testdata/webp/ll_1x1.webp +0 -0
  297. package/dist/lib/image/testdata/webp/ll_alpha_29x21.webp +0 -0
  298. package/dist/lib/image/testdata/webp/ll_gradient_64x64.webp +0 -0
  299. package/dist/lib/image/testdata/webp/ll_meta_32x32.webp +0 -0
  300. package/dist/lib/image/testdata/webp/ll_noise_17x9.webp +0 -0
  301. package/dist/lib/image/testdata/webp/ll_pal11_23x11.webp +0 -0
  302. package/dist/lib/image/testdata/webp/ll_pal2_19x7.webp +0 -0
  303. package/dist/lib/image/testdata/webp/ll_pal40_16x16.webp +0 -0
  304. package/dist/lib/image/testdata/webp/ll_pal4_13x5.webp +0 -0
  305. package/dist/lib/image/testdata/webp/ll_photo_40x30.webp +0 -0
  306. package/dist/lib/image/testdata/webp/ll_predictors_64x32.webp +0 -0
  307. package/dist/lib/image/testdata/webp/ly_1x1.webp +0 -0
  308. package/dist/lib/image/testdata/webp/ly_alph_raw_f0_21x13.webp +0 -0
  309. package/dist/lib/image/testdata/webp/ly_alph_raw_f1_21x13.webp +0 -0
  310. package/dist/lib/image/testdata/webp/ly_alph_raw_f2_21x13.webp +0 -0
  311. package/dist/lib/image/testdata/webp/ly_alph_raw_f3_21x13.webp +0 -0
  312. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f0_21x13.webp +0 -0
  313. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f1_21x13.webp +0 -0
  314. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f2_21x13.webp +0 -0
  315. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f3_21x13.webp +0 -0
  316. package/dist/lib/image/testdata/webp/ly_alpha_33x17.webp +0 -0
  317. package/dist/lib/image/testdata/webp/ly_exif_15x11.webp +0 -0
  318. package/dist/lib/image/testdata/webp/ly_i16_96x80.webp +0 -0
  319. package/dist/lib/image/testdata/webp/ly_nofilter_24x20.webp +0 -0
  320. package/dist/lib/image/testdata/webp/ly_odd_17x9.webp +0 -0
  321. package/dist/lib/image/testdata/webp/ly_photo_48x40.webp +0 -0
  322. package/dist/lib/image/testdata/webp/ly_q100_20x18.webp +0 -0
  323. package/dist/lib/image/testdata/webp/ly_sharp_40x36.webp +0 -0
  324. package/dist/lib/image/testdata/webp/ly_simple_filter_33x31.webp +0 -0
  325. package/dist/lib/image/testdata/webp/ly_vpx_parts8_37x45.webp +0 -0
  326. package/dist/lib/image/testdata/webp/ly_vpx_skip_96x80.webp +0 -0
  327. package/dist/lib/image/tests/WebPDecodeTool.rgr +81 -0
  328. package/dist/lib/image/tests/WebPDecoderTest.rgr +1162 -0
  329. package/dist/lib/image/tests/run_webp_tests.sh +39 -0
  330. package/dist/lib/rust/RsJson.rgr +468 -0
  331. package/dist/lib/rust/RsPrelude.rgr +1663 -0
  332. package/dist/lib/shell_test.rgr +7 -7
  333. package/dist/lib/stdlib.rgr +21 -5
  334. package/dist/lib/zip/ranger.json +6 -0
  335. package/dist/rgrc.js +87318 -67610
  336. package/package.json +1010 -1040
  337. package/dist/README.md +0 -117
  338. package/dist/package.json +0 -47
@@ -0,0 +1,303 @@
1
+ // SPDX-License-Identifier: MIT
2
+ //
3
+ // A real text-input session for a canvas that draws its own fields.
4
+ //
5
+ // THE ARGUMENT. A canvas UI has no text field, so the obvious thing is to turn
6
+ // `keydown` into edits: a printable key inserts, Backspace deletes, Ctrl+Arrow
7
+ // moves by a word. That is what this codebase did, and it is a dead end — not
8
+ // because it is hard, but because the list of things it cannot do never ends:
9
+ // IME and dead keys, the clipboard, undo, emoji, mobile keyboards that send no
10
+ // per-character keydown at all, and platform-specific word boundaries.
11
+ //
12
+ // So the platform owns the editing session instead. A real `<input>` sits over
13
+ // the drawn field, transparent and one pixel of nothing; it receives the keys,
14
+ // the IME, the paste and the undo; and Ranger MIRRORS its state. Ranger keeps
15
+ // what it is good at — the tree, the layout, the styles, the hit targets, the
16
+ // pixels — and hands over the one system service the platform genuinely knows
17
+ // better.
18
+ //
19
+ // WHAT WAS MEASURED FIRST (conformance/oracle/textinput.json, from a real
20
+ // `<input>` driven through the DevTools protocol, IME composition included):
21
+ //
22
+ // `beforeinput` fires with the OLD value; `input` fires with the new one.
23
+ // So this can be a plain mirror — read `value`, `selectionStart` and
24
+ // `selectionEnd` on `input` — and never has to diff or replay an inputType.
25
+ // That one fact is the whole design.
26
+ //
27
+ // Composition arrives as compositionstart, then compositionupdate +
28
+ // beforeinput/input `insertCompositionText` per keystroke, then
29
+ // compositionend. At `beforeinput` the selection is the range being
30
+ // replaced and `data` is what replaces it, so the composing range is
31
+ // `selectionStart .. selectionStart + data.length` — which is what a field
32
+ // has to underline, and the one part a hidden proxy cannot draw for us.
33
+ //
34
+ // Copy, cut, paste and undo need no code at all: they arrive as
35
+ // `insertFromPaste`, `deleteByCut`, `historyUndo` and `historyRedo` like any
36
+ // other edit.
37
+ //
38
+ // And one Backspace removes 1 code unit from "abc", 2 from an emoji, 4 from
39
+ // a flag and 11 from a ZWJ family — while ArrowLeft over a combining acute
40
+ // skips 2 where Backspace removes 1. Chromium's own delete and its own
41
+ // caret motion disagree about that cluster. A hand-written grapheme walker
42
+ // would have to reproduce an inconsistency rather than a standard; through
43
+ // the proxy there is nothing to reproduce.
44
+ //
45
+ // WHAT THIS DELIBERATELY DOES NOT DO. It does not draw anything, it does not
46
+ // decide what a field looks like, and it does not know what a field IS. It
47
+ // takes a value and a selection in and reports a value and a selection out.
48
+
49
+ /**
50
+ * @param {object} opts
51
+ * @param {HTMLElement} opts.host where to park the proxy
52
+ * @param {HTMLCanvasElement} opts.canvas the element that keeps focus when no
53
+ * field is active
54
+ * @param {(edit: {value: string, selStart: number, selEnd: number,
55
+ * inputType: string, isComposing: boolean}) => void} opts.onEdit
56
+ * @param {(c: {active: boolean, start: number, end: number, text: string}) => void} [opts.onComposition]
57
+ * @param {(k: {key: string, shiftKey: boolean, ctrlKey: boolean,
58
+ * metaKey: boolean, altKey: boolean,
59
+ * preventDefault: () => void}) => boolean} [opts.onKey]
60
+ * Keys the APPLICATION owns rather than the field: Tab, Escape, and
61
+ * anything that opens a menu. Returning true consumes the key.
62
+ */
63
+ export function createTextInputBridge({ host, canvas, onEdit, onComposition, onKey }) {
64
+ // ONE PROXY PER SESSION, not one for the page. Chromium keeps an input's
65
+ // undo history across a programmatic `value` write when the input is not
66
+ // focused at the time, so a proxy reused from field to field carried the
67
+ // last field's edits in its history: measured, the third Ctrl+Z in Full
68
+ // Name — after two had taken back the typed "zz" — restored a state from
69
+ // the session before it, with the caret at 0. A fourth would have put
70
+ // another field's text into this one. A fresh element has an empty history,
71
+ // which is what a fresh field has.
72
+ const makeProxy = () => {
73
+ const own = document.createElement("input");
74
+ own.type = "text";
75
+ // Off the accessibility tree: the drawn field already has a `textbox` node
76
+ // with a name and a value, and two text boxes for one control is one too
77
+ // many for a reader. The proxy is a keyboard fixture, not a control.
78
+ own.setAttribute("aria-hidden", "true");
79
+ own.tabIndex = -1;
80
+ own.autocapitalize = "off";
81
+ own.autocomplete = "off";
82
+ own.spellcheck = false;
83
+ // Positioned over the field rather than off-screen. An off-screen input is
84
+ // the usual trick and it is wrong on a phone: the browser scrolls to the
85
+ // focused element and to the composition popup, so an input at -9999px
86
+ // takes the page with it. Transparent and in place costs nothing and keeps
87
+ // the IME candidate window next to the text it is composing.
88
+ Object.assign(own.style, {
89
+ position: "absolute",
90
+ opacity: "0",
91
+ padding: "0",
92
+ margin: "0",
93
+ border: "0",
94
+ outline: "none",
95
+ background: "transparent",
96
+ color: "transparent",
97
+ caretColor: "transparent",
98
+ // SIXTEEN PIXELS, for iOS. Safari zooms the page in when it focuses a
99
+ // text field that computes to less than 16px, and this proxy is what
100
+ // takes the keyboard for every drawn field. It inherited whatever the
101
+ // host had, which on a phone-sized page is smaller than that. The
102
+ // proxy is transparent and clipped to the field's box, so the size is
103
+ // invisible and only Safari's decision depends on it.
104
+ fontSize: "16px",
105
+ zIndex: "1",
106
+ // It must not take the pointer. Ranger does every hit test and places
107
+ // every caret; the proxy only needs the keyboard, and it is sitting
108
+ // exactly on top of the field it serves. Without this it swallows the
109
+ // pointermove over its own box — measured: the I-beam cursor stopped
110
+ // appearing the moment a field was focused, because the canvas never saw
111
+ // the pointer again.
112
+ pointerEvents: "none",
113
+ });
114
+ own.style.display = "none";
115
+ host.appendChild(own);
116
+ return own;
117
+ };
118
+ let own = makeProxy();
119
+ let el = own;
120
+
121
+ let active = null; // the tid of the field the session belongs to
122
+ let composing = false;
123
+ let echo = false; // set while WE are writing to the proxy
124
+ // The elements the listeners below have been put on: the own proxy once,
125
+ // and every mirror input the session has been handed.
126
+ const wired = new WeakSet();
127
+
128
+ const report = (inputType, isComposing) => {
129
+ if (echo) return;
130
+ onEdit({
131
+ value: el.value,
132
+ selStart: el.selectionStart ?? 0,
133
+ selEnd: el.selectionEnd ?? 0,
134
+ inputType: inputType || "",
135
+ isComposing: !!isComposing,
136
+ });
137
+ };
138
+
139
+ function wire(target) {
140
+ if (wired.has(target)) return;
141
+ wired.add(target);
142
+ // Only the element the session is on reports: a mirror input the session
143
+ // left keeps its listeners and must stay quiet.
144
+ const mine = () => target === el && active !== null;
145
+ target.addEventListener("input", (ev) => { if (mine()) report(ev.inputType, ev.isComposing); });
146
+
147
+ // The composing range, for the underline. Taken at `beforeinput`, where
148
+ // the selection is still the range about to be replaced — after `input`
149
+ // it has collapsed to the caret and the range is gone.
150
+ target.addEventListener("beforeinput", (ev) => {
151
+ if (!mine() || !onComposition) return;
152
+ if (ev.inputType !== "insertCompositionText") return;
153
+ const start = target.selectionStart ?? 0;
154
+ const text = ev.data || "";
155
+ onComposition({ active: true, start, end: start + text.length, text });
156
+ });
157
+ target.addEventListener("compositionend", () => {
158
+ if (!mine()) return;
159
+ composing = false;
160
+ if (onComposition) onComposition({ active: false, start: 0, end: 0, text: "" });
161
+ });
162
+ target.addEventListener("compositionstart", () => {
163
+ if (mine()) composing = true;
164
+ });
165
+
166
+ // The selection can move without an edit: an arrow key, Ctrl+A, a
167
+ // double-click, a drag with the mouse. Those are the platform's word and
168
+ // grapheme rules doing exactly what the bridge exists to borrow, so they
169
+ // are mirrored like any other change.
170
+ target.addEventListener("keyup", () => { if (mine()) report("", composing); });
171
+ target.addEventListener("select", () => { if (mine()) report("", composing); });
172
+ target.addEventListener("mouseup", () => { if (mine()) report("", composing); });
173
+
174
+ // Keys the application owns. A field must not swallow Tab or Escape, and
175
+ // the page's own shortcuts have to keep working while a field has focus.
176
+ target.addEventListener("keydown", (ev) => {
177
+ if (!mine() || !onKey) return;
178
+ if (ev.isComposing) return; // an IME is using this key; it is not ours
179
+ const taken = onKey({
180
+ key: ev.key,
181
+ shiftKey: ev.shiftKey,
182
+ ctrlKey: ev.ctrlKey,
183
+ metaKey: ev.metaKey,
184
+ altKey: ev.altKey,
185
+ preventDefault: () => ev.preventDefault(),
186
+ });
187
+ if (taken) ev.preventDefault();
188
+ });
189
+ }
190
+ wire(own);
191
+
192
+ // A mirror's input, while the session is in it, takes the pointer: a click
193
+ // puts the caret where the platform says, a drag selects, a double-click
194
+ // takes the word — and every one of those comes back through `select` and
195
+ // `mouseup` for the app to draw. The canvas keeps everything outside it.
196
+ function takePointer(target, yes) {
197
+ if (target === own) return;
198
+ target.style.pointerEvents = yes ? "auto" : "none";
199
+ target.style.cursor = yes ? "text" : "";
200
+ target.style.caretColor = "transparent";
201
+ }
202
+
203
+ return {
204
+ /** True while a field owns the keyboard. */
205
+ isActive: () => active !== null,
206
+ activeTid: () => active,
207
+ isComposing: () => composing,
208
+
209
+ /**
210
+ * Hand the session to a field. `box` is where the field is drawn, in
211
+ * canvas coordinates, so the proxy can sit on top of it.
212
+ */
213
+ focusField(tid, { value, selStart, selEnd, kind, maxLength, readOnly, box }, element) {
214
+ // The element the session edits in: the accessibility mirror's own
215
+ // input for this field when the host has one — then the reader, the
216
+ // keyboard and the pointer all meet in one element and Tab walks on
217
+ // from it to the next control — and the hidden proxy otherwise.
218
+ // A field of our own gets a NEW proxy — see `makeProxy`. A mirror input
219
+ // is the host's element and keeps whatever history the host gives it.
220
+ if (!element) {
221
+ const fresh = makeProxy();
222
+ if (el === own) takePointer(own, false);
223
+ own.remove();
224
+ own = fresh;
225
+ }
226
+ const next = element || own;
227
+ if (next !== el) {
228
+ takePointer(el, false);
229
+ if (el === own) own.style.display = "none";
230
+ el = next;
231
+ wire(el);
232
+ }
233
+ takePointer(el, true);
234
+ active = tid;
235
+ echo = true;
236
+ // `type` is the platform's, not ours. A password proxy gives the right
237
+ // reveal behaviour and the right keyboard; a number proxy gives a
238
+ // numeric keypad on a phone. The character filtering `InputCtl` grew by
239
+ // hand belongs here instead, where the platform already does it.
240
+ el.type = kind === "password" ? "password" : "text";
241
+ el.inputMode = kind === "number" ? "decimal" : kind === "email" ? "email" : "text";
242
+ el.readOnly = !!readOnly;
243
+ if (maxLength > 0) el.maxLength = maxLength;
244
+ else el.removeAttribute("maxlength");
245
+ el.value = value;
246
+ el.setSelectionRange(selStart, selEnd);
247
+ if (box && el === own) {
248
+ el.style.display = "block";
249
+ el.style.left = box.x + "px";
250
+ el.style.top = box.y + "px";
251
+ el.style.width = box.w + "px";
252
+ el.style.height = box.h + "px";
253
+ }
254
+ if (document.activeElement !== el) el.focus({ preventScroll: true });
255
+ echo = false;
256
+ },
257
+
258
+ /**
259
+ * Ranger changed the state — a click moved the caret, say.
260
+ *
261
+ * This also takes the focus BACK, and has to: the page focuses its canvas
262
+ * on every pointerdown so that keys reach it, which quietly ends the
263
+ * session on the second click of a double-click. Measured — the word was
264
+ * selected in Ranger, the proxy still read 4,4 and unfocused, and the
265
+ * keystroke went round the old keydown path and inserted instead of
266
+ * replacing. While a session is active the proxy holds the keyboard, and
267
+ * "active" is not a thing anything else gets to decide by accident.
268
+ */
269
+ sync({ value, selStart, selEnd }) {
270
+ if (active === null) return;
271
+ echo = true;
272
+ if (el.value !== value) el.value = value;
273
+ el.setSelectionRange(selStart, selEnd);
274
+ if (document.activeElement !== el) el.focus({ preventScroll: true });
275
+ echo = false;
276
+ },
277
+
278
+ blurField() {
279
+ if (active === null) return;
280
+ this.release();
281
+ if (canvas) canvas.focus({ preventScroll: true });
282
+ },
283
+
284
+ /**
285
+ * End the session and leave the focus where it is going. Tab out of a
286
+ * field is this: the browser moves the focus to the next control, and
287
+ * the canvas must not take it back on the way.
288
+ */
289
+ release() {
290
+ if (active === null) return;
291
+ active = null;
292
+ composing = false;
293
+ takePointer(el, false);
294
+ if (el === own) {
295
+ own.style.display = "none";
296
+ own.value = "";
297
+ }
298
+ },
299
+
300
+ /** For tests and for anything that needs to see the real element. */
301
+ element: () => el,
302
+ };
303
+ }
@@ -0,0 +1,144 @@
1
+ // SPDX-License-Identifier: MIT
2
+ //
3
+ // When a built frame may be drawn again, and when it has to be built.
4
+ //
5
+ // A display list that carries a camera (`EVGDisplayList.setView`) can be
6
+ // drawn at a view it was not built at: the painter multiplies in the shader,
7
+ // so a pan costs a uniform rather than a walk, a layout and a flatten
8
+ // (PLAN_VIEW_TRANSFORM.md). Two things stop that being true for every view,
9
+ // and this is the arithmetic that decides:
10
+ //
11
+ // THE BAND. A run was rasterised into the glyph atlas at a size and a curve
12
+ // was flattened for one. Stretched far enough, text blurs and a circle
13
+ // shows its facets; shrunk far enough, the frame carries points nobody can
14
+ // see. So a frame is good between `1/band` and `band` of the scale it was
15
+ // built at — √2 by default, about three notches of a pinch.
16
+ //
17
+ // THE REGION. Culling asks what is inside the frame, and a frame drawn at a
18
+ // view it was not built at shows scene the build never considered. So a
19
+ // frame is built for the viewport GROWN by an overscan, and it is good
20
+ // until the viewport leaves that.
21
+ //
22
+ // Both are host decisions rather than engine ones — a viewer that would
23
+ // rather have sharp text than frames picks a tighter band, and one on a
24
+ // phone picks a smaller overscan — which is why they are here and not in the
25
+ // display list.
26
+ //
27
+ // Everything in this file is arithmetic on plain numbers: no GL, no DOM, and
28
+ // `view-policy-check.mjs` holds it to its own rules without a browser.
29
+
30
+ /** The default overscan: one viewport of scene in every direction. */
31
+ export const DEFAULT_OVERSCAN = 1;
32
+
33
+ /** The default band: √2 either way. See the note above. */
34
+ export const DEFAULT_BAND = Math.SQRT2;
35
+
36
+ const scaleOf = (v) => {
37
+ const s = v && v.scale;
38
+ return s === undefined || s === null || s === 0 ? 1 : s;
39
+ };
40
+
41
+ /**
42
+ * What the canvas shows, in scene coordinates.
43
+ *
44
+ * The inverse of the camera: a point on the page is `scene * scale + pan`, so
45
+ * the scene under the page is `(page - pan) / scale`.
46
+ */
47
+ export function sceneViewport(view, width, height) {
48
+ const s = scaleOf(view);
49
+ const x = ((view && view.x) || 0);
50
+ const y = ((view && view.y) || 0);
51
+ return { x: -x / s, y: -y / s, w: width / s, h: height / s };
52
+ }
53
+
54
+ /**
55
+ * The region to build for: what the canvas shows, grown by the overscan.
56
+ *
57
+ * `overscan` is in viewports, not pixels, so the same number means the same
58
+ * thing at every zoom — one viewport each way is 9× the area in the worst
59
+ * case and usually far less, since a board at 8× has almost nothing on it.
60
+ */
61
+ export function regionFor(view, width, height, overscan = DEFAULT_OVERSCAN) {
62
+ const v = sceneViewport(view, width, height);
63
+ const gx = v.w * overscan;
64
+ const gy = v.h * overscan;
65
+ return { x: v.x - gx, y: v.y - gy, w: v.w + gx * 2, h: v.h + gy * 2 };
66
+ }
67
+
68
+ /** Is `inner` wholly inside `outer`? */
69
+ export function rectInside(inner, outer) {
70
+ return (
71
+ inner.x >= outer.x &&
72
+ inner.y >= outer.y &&
73
+ inner.x + inner.w <= outer.x + outer.w &&
74
+ inner.y + inner.h <= outer.y + outer.h
75
+ );
76
+ }
77
+
78
+ /**
79
+ * May a frame built as `built` be drawn at `view` on a `width` x `height`
80
+ * canvas — and if not, why not?
81
+ *
82
+ * `built` is `{ view, region }`: the camera the list was walked at and the
83
+ * scene it was walked for. Returns `{ keep, reason }`, and the reason is
84
+ * what a host prints when someone asks why a pan cost a rebuild.
85
+ */
86
+ export function frameFits(built, view, width, height, opts = {}) {
87
+ if (!built || !built.view || !built.region) return { keep: false, reason: "nothing built" };
88
+ const band = opts.band || DEFAULT_BAND;
89
+ const ratio = scaleOf(view) / scaleOf(built.view);
90
+ if (ratio > band || ratio < 1 / band) {
91
+ return { keep: false, reason: "scale left the band", ratio };
92
+ }
93
+ const shown = sceneViewport(view, width, height);
94
+ if (!rectInside(shown, built.region)) {
95
+ return { keep: false, reason: "viewport left the region" };
96
+ }
97
+ return { keep: true, reason: "" };
98
+ }
99
+
100
+ /**
101
+ * A frame keeper: the state above, with the two calls a host makes.
102
+ *
103
+ * const keep = createViewKeeper({ overscan: 1 });
104
+ * if (!keep.fits(view, w, h).keep) { …build…; keep.built(view, w, h); }
105
+ * frame.draw(shifts, view);
106
+ *
107
+ * `built` records what the host just walked, and returns the region it
108
+ * should have walked for — a host that culls to it passes the region to the
109
+ * engine BEFORE building, so the two calls are `regionFor` then `built`.
110
+ */
111
+ export function createViewKeeper(opts = {}) {
112
+ const overscan = opts.overscan === undefined ? DEFAULT_OVERSCAN : opts.overscan;
113
+ const band = opts.band || DEFAULT_BAND;
114
+ let state = null;
115
+ let kept = 0;
116
+ let builds = 0;
117
+ return {
118
+ /** The region a build at this view should cover. */
119
+ region: (view, w, h) => regionFor(view, w, h, overscan),
120
+ /** Can the frame in hand be drawn at this view? */
121
+ fits(view, w, h) {
122
+ const f = frameFits(state, view, w, h, { band });
123
+ if (f.keep) kept += 1;
124
+ return f;
125
+ },
126
+ /** Remember what was just built, and for what. */
127
+ built(view, w, h) {
128
+ builds += 1;
129
+ state = { view: { x: view.x || 0, y: view.y || 0, scale: scaleOf(view) }, region: regionFor(view, w, h, overscan) };
130
+ return state.region;
131
+ },
132
+ /** Throw the frame away: a new document, an edit, a resize. */
133
+ reset() {
134
+ state = null;
135
+ },
136
+ get state() {
137
+ return state;
138
+ },
139
+ /** Draws served from a kept frame, and builds. For a status line. */
140
+ get counts() {
141
+ return { kept, builds };
142
+ },
143
+ };
144
+ }