ranger-compiler 3.5.1 → 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 +1064 -20
  2. package/LICENSE +3 -1
  3. package/README.md +123 -28
  4. package/dist/Lang.rgr +1188 -290
  5. package/dist/api.d.ts +2343 -879
  6. package/dist/api.js +79923 -56921
  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,46 @@
1
+ <!doctype html>
2
+ <meta charset="utf-8">
3
+ <title>EVG on WebGL</title>
4
+ <style>
5
+ /* The same TTFs EVG measured with. Without them the browser substitutes a
6
+ system face: the positions would still be EVG's, but the glyphs would not
7
+ be the ones the PDF is set in, so the comparison would prove nothing. */
8
+ @font-face { font-family:"Cinzel"; src:url("../../../gallery/pdf_writer/assets/fonts/Cinzel/Cinzel-Regular.ttf"); }
9
+ @font-face { font-family:"Noto Sans"; src:url("../../../gallery/pdf_writer/assets/fonts/Noto_Sans/NotoSans-Regular.ttf"); }
10
+ @font-face { font-family:"Josefin Sans"; src:url("../../../gallery/pdf_writer/assets/fonts/Josefin_Sans/JosefinSans-Regular.ttf"); }
11
+ @font-face { font-family:"Josefin Sans-Bold"; src:url("../../../gallery/pdf_writer/assets/fonts/Josefin_Sans/JosefinSans-Bold.ttf"); }
12
+ @font-face { font-family:"Noto Sans-Bold"; src:url("../../../gallery/pdf_writer/assets/fonts/Noto_Sans/NotoSans-Bold.ttf"); }
13
+ body { margin:0; background:#8a8a8a; display:flex; justify-content:center; padding:24px; font:14px system-ui }
14
+ canvas { background:#fff; box-shadow:0 2px 18px rgba(0,0,0,.35) }
15
+ #err { color:#900; font:13px monospace; white-space:pre-wrap }
16
+ </style>
17
+ <div>
18
+ <canvas id="c"></canvas>
19
+ <p id="err"></p>
20
+ </div>
21
+ <script type="module">
22
+ import { renderDisplayList } from "./evg-webgl.js";
23
+ const url = new URLSearchParams(location.search).get("list") || "boxmodel.json";
24
+ try {
25
+ const doc = await (await fetch(url)).json();
26
+ const dpr = Math.min(2, window.devicePixelRatio || 1);
27
+ const c = document.getElementById("c");
28
+ c.style.width = doc.width + "px";
29
+ c.style.height = doc.height + "px";
30
+ c.width = Math.round(doc.width * dpr);
31
+ c.height = Math.round(doc.height * dpr);
32
+ const gl = c.getContext("webgl2", { antialias: true, premultipliedAlpha: false, stencil: true });
33
+ if (!gl) throw new Error("WebGL 2 not available");
34
+ await document.fonts.ready;
35
+ // document.fonts.ready resolves before a face that nothing has used yet is
36
+ // fetched, so ask for each size the list actually needs.
37
+ await Promise.all(doc.list.cmds.filter(c => c.text)
38
+ .map(c => document.fonts.load(`${c.size}px "${c.font}"`)));
39
+ const stats = renderDisplayList(gl, doc, { dpr });
40
+ window.__evgStats = stats;
41
+ document.title = `EVG on WebGL — ${stats.drawn} quads`;
42
+ } catch (e) {
43
+ document.getElementById("err").textContent = String(e && e.stack || e);
44
+ window.__evgStats = { error: String(e) };
45
+ }
46
+ </script>
@@ -0,0 +1,285 @@
1
+ /* SPDX-License-Identifier: MIT
2
+ *
3
+ * Presets: effects that are already a look.
4
+ *
5
+ * Each block below is one element's worth of CSS. The gallery's effects demo
6
+ * (`?demo=effects`) has them in its rail and types the one you pick into the
7
+ * stylesheet under its canvas; or copy one into a sheet of your own. Every
8
+ * effect here is a name and some numbers; there is no code to copy with them.
9
+ *
10
+ * WHAT EACH BLOCK MUST CARRY is `evg-surface-effect` (which effect),
11
+ * `evg-effect-on: always` where it moves on its own clock, its own
12
+ * `background-color` — the effects draw OVER what the element paints — and
13
+ * whatever `evg-fx-*` numbers it wants. Anything left out takes the plugin's
14
+ * own default.
15
+ *
16
+ * Rendered by `lib/evg/gl/effect-shots.mjs`, and read by the engine's own
17
+ * cascade in `lib/evg/gl/fx-check.mjs`, which holds every preset here to
18
+ * producing the effect it names.
19
+ */
20
+
21
+ /* ============================================================ starfield === */
22
+
23
+ .sky-deep {
24
+ background-color: rgb(6, 7, 20);
25
+ evg-surface-effect: starfield;
26
+ evg-effect-on: always;
27
+ evg-fx-density: 1.5;
28
+ evg-fx-nebula: 0.8;
29
+ evg-fx-hue: 228;
30
+ evg-fx-hue2: 305;
31
+ evg-fx-speed: 6;
32
+ evg-fx-angle: 200;
33
+ evg-fx-seed: 5;
34
+ }
35
+
36
+ /* EMBER. A warm cloud — orange near, deep red far — with fewer, larger stars,
37
+ * so the dust carries the picture and the stars sit in it. */
38
+ .sky-ember {
39
+ background-color: rgb(16, 6, 8);
40
+ evg-surface-effect: starfield;
41
+ evg-effect-on: always;
42
+ evg-fx-density: 0.9;
43
+ evg-fx-nebula: 0.95;
44
+ evg-fx-hue: 22;
45
+ evg-fx-hue2: 348;
46
+ evg-fx-glow: 1.5;
47
+ evg-fx-twinkle: 0.7;
48
+ evg-fx-speed: 4;
49
+ evg-fx-angle: 170;
50
+ evg-fx-seed: 12;
51
+ }
52
+
53
+ /* AURORA. Green near, teal far, and a dense field of small stars behind it —
54
+ * the dust reads as a curtain rather than as a cloud. */
55
+ .sky-aurora {
56
+ background-color: rgb(4, 14, 14);
57
+ evg-surface-effect: starfield;
58
+ evg-effect-on: always;
59
+ evg-fx-density: 2.4;
60
+ evg-fx-nebula: 0.75;
61
+ evg-fx-hue: 150;
62
+ evg-fx-hue2: 186;
63
+ evg-fx-glow: 0.9;
64
+ evg-fx-twinkle: 1.2;
65
+ evg-fx-speed: 9;
66
+ evg-fx-angle: 215;
67
+ evg-fx-seed: 3;
68
+ }
69
+
70
+ /* ROSE. Pink near, violet far, slow, with the glow turned up: the sky of a
71
+ * marketing hero rather than of an observatory. */
72
+ .sky-rose {
73
+ background-color: rgb(14, 6, 16);
74
+ evg-surface-effect: starfield;
75
+ evg-effect-on: always;
76
+ evg-fx-density: 1.2;
77
+ evg-fx-nebula: 0.9;
78
+ evg-fx-hue: 330;
79
+ evg-fx-hue2: 268;
80
+ evg-fx-glow: 1.6;
81
+ evg-fx-twinkle: 0.8;
82
+ evg-fx-speed: 3;
83
+ evg-fx-angle: 190;
84
+ evg-fx-seed: 21;
85
+ }
86
+
87
+ /* CLEAR NIGHT. Almost no dust and a hard, bright field: what a sky looks like
88
+ * when the parameter that does most of the work is turned off. */
89
+ .sky-clear {
90
+ background-color: rgb(3, 4, 12);
91
+ evg-surface-effect: starfield;
92
+ evg-effect-on: always;
93
+ evg-fx-density: 2.8;
94
+ evg-fx-nebula: 0.1;
95
+ evg-fx-hue: 205;
96
+ evg-fx-hue2: 225;
97
+ evg-fx-glow: 1.3;
98
+ evg-fx-twinkle: 1.4;
99
+ evg-fx-speed: 5;
100
+ evg-fx-angle: 200;
101
+ evg-fx-seed: 8;
102
+ }
103
+
104
+ /* ============================================================ plasma =========
105
+ *
106
+ * Ribbons of light crossing a dark ground. A SOURCE effect: it paints into the
107
+ * element's background, so anything the element contains is drawn over it. */
108
+
109
+ /* TIDE. Blue into violet, five ribbons, slow. The quiet one. */
110
+ .fx-tide {
111
+ background-color: rgb(4, 6, 24);
112
+ evg-surface-effect: plasma-wave;
113
+ evg-effect-on: always;
114
+ evg-fx-ribbons: 5;
115
+ evg-fx-speed: 0.3;
116
+ evg-fx-amp: 0.2;
117
+ evg-fx-freq: 1.6;
118
+ evg-fx-width: 2.4;
119
+ evg-fx-glow: 34;
120
+ evg-fx-sheet: 0.2;
121
+ evg-fx-hue: 222;
122
+ evg-fx-hue2: 288;
123
+ evg-fx-grain: 0.35;
124
+ evg-fx-seed: 4;
125
+ }
126
+
127
+ /* SIGNAL. Tighter, faster, more of them, and a cyan end — a waveform rather
128
+ * than a tide. */
129
+ .fx-signal {
130
+ background-color: rgb(3, 8, 18);
131
+ evg-surface-effect: plasma-wave;
132
+ evg-effect-on: always;
133
+ evg-fx-ribbons: 7;
134
+ evg-fx-speed: 0.7;
135
+ evg-fx-amp: 0.3;
136
+ evg-fx-freq: 2.6;
137
+ evg-fx-width: 1.5;
138
+ evg-fx-glow: 16;
139
+ evg-fx-sheet: 0.06;
140
+ evg-fx-hue: 186;
141
+ evg-fx-hue2: 262;
142
+ evg-fx-grain: 0.5;
143
+ evg-fx-seed: 9;
144
+ }
145
+
146
+ /* ============================================================ raindrop ======
147
+ *
148
+ * Water on the surface. A BACKDROP effect: each drop is a lens over whatever
149
+ * is behind the element, so a drop over a photograph shows the photograph and
150
+ * a drop over a flat card shows the card and its own highlight. */
151
+
152
+ /* GLASS. Rain on a dark pane: many small drops, a few large, light from the
153
+ * upper left. */
154
+ .fx-rain {
155
+ background-color: rgb(14, 14, 16);
156
+ evg-surface-effect: raindrop;
157
+ evg-fx-density: 1.1;
158
+ evg-fx-size: 0.5;
159
+ evg-fx-refract: 14;
160
+ evg-fx-shine: 0.9;
161
+ evg-fx-angle: -55;
162
+ evg-fx-rim: 0.6;
163
+ evg-fx-seed: 2;
164
+ }
165
+
166
+ /* DOWNPOUR. Fewer, bigger, and drifting — the field moves, which is what a
167
+ * still picture of rain never does. */
168
+ .fx-downpour {
169
+ background-color: rgb(10, 12, 18);
170
+ evg-surface-effect: raindrop;
171
+ evg-effect-on: always;
172
+ evg-fx-density: 0.6;
173
+ evg-fx-size: 0.7;
174
+ evg-fx-refract: 22;
175
+ evg-fx-shine: 0.8;
176
+ evg-fx-angle: -60;
177
+ evg-fx-rim: 0.5;
178
+ evg-fx-speed: 7;
179
+ evg-fx-seed: 6;
180
+ }
181
+
182
+ /* ======================================================== ambient light =====
183
+ *
184
+ * A wash of colour with soft lights adrift in it. Nothing in it is sharp,
185
+ * which is the point: it goes BEHIND real content. */
186
+
187
+ /* LAGOON. Teal into violet, seven lights, barely moving. */
188
+ .fx-lagoon {
189
+ background-color: rgb(8, 14, 22);
190
+ evg-surface-effect: ambient-light;
191
+ evg-effect-on: always;
192
+ evg-fx-hue: 186;
193
+ evg-fx-hue2: 272;
194
+ evg-fx-sat: 0.45;
195
+ evg-fx-tilt: 25;
196
+ evg-fx-depth: 0.5;
197
+ evg-fx-orbs: 7;
198
+ evg-fx-size: 0.6;
199
+ evg-fx-softness: 1.5;
200
+ evg-fx-speed: 0.06;
201
+ evg-fx-glow: 0.5;
202
+ evg-fx-seed: 2;
203
+ }
204
+
205
+ /* DUSK. Warm, dimmer, fewer and larger lights — a background for a page with
206
+ * a lot of text on it. */
207
+ .fx-dusk {
208
+ background-color: rgb(16, 10, 16);
209
+ evg-surface-effect: ambient-light;
210
+ evg-effect-on: always;
211
+ evg-fx-hue: 338;
212
+ evg-fx-hue2: 28;
213
+ evg-fx-sat: 0.3;
214
+ evg-fx-tilt: 200;
215
+ evg-fx-depth: 0.42;
216
+ evg-fx-orbs: 4;
217
+ evg-fx-size: 0.85;
218
+ evg-fx-softness: 1.9;
219
+ evg-fx-speed: 0.05;
220
+ evg-fx-glow: 0.42;
221
+ evg-fx-seed: 11;
222
+ }
223
+
224
+ /* ================================================================ smoke === */
225
+
226
+ /* STAGE. A floor full of it: dense along the bottom, billows to the middle,
227
+ * single tendrils past that, and black above. The reference is a smoke machine
228
+ * lit from one side. */
229
+ .fx-stage {
230
+ background-color: rgb(6, 6, 8);
231
+ evg-surface-effect: smoke;
232
+ evg-effect-on: always;
233
+ evg-fx-density: 1.25;
234
+ evg-fx-rise: 0.05;
235
+ evg-fx-swirl: 2.6;
236
+ evg-fx-scale: 190;
237
+ evg-fx-height: 0.9;
238
+ evg-fx-softness: 0.55;
239
+ evg-fx-shade: 0.6;
240
+ evg-fx-angle: -60;
241
+ evg-fx-hue: 205;
242
+ evg-fx-tint: 0.1;
243
+ evg-fx-seed: 3;
244
+ }
245
+
246
+ /* CLOUD. The same smoke with nowhere to settle: it fills the box, drifts
247
+ * sideways as well as up, and is lit from higher. A wall of weather rather
248
+ * than a floor of it. */
249
+ .fx-cloud {
250
+ background-color: rgb(7, 8, 12);
251
+ evg-surface-effect: smoke;
252
+ evg-effect-on: always;
253
+ evg-fx-density: 1;
254
+ evg-fx-rise: 0.03;
255
+ evg-fx-wind: 0.6;
256
+ evg-fx-swirl: 2.4;
257
+ evg-fx-scale: 240;
258
+ evg-fx-height: 2.5;
259
+ evg-fx-softness: 0.6;
260
+ evg-fx-shade: 0.5;
261
+ evg-fx-angle: -70;
262
+ evg-fx-hue: 212;
263
+ evg-fx-tint: 0.15;
264
+ evg-fx-seed: 4;
265
+ }
266
+
267
+ /* HAZE. Thin, high and blowing sideways, at four octaves — the cheap one: a
268
+ * fog to put a page on top of rather than the subject of one. */
269
+ .fx-haze {
270
+ background-color: rgb(8, 9, 14);
271
+ evg-surface-effect: smoke;
272
+ evg-effect-on: always;
273
+ evg-fx-density: 0.7;
274
+ evg-fx-rise: 0.02;
275
+ evg-fx-wind: 1.2;
276
+ evg-fx-swirl: 1.8;
277
+ evg-fx-scale: 200;
278
+ evg-fx-detail: 4;
279
+ evg-fx-height: 1.6;
280
+ evg-fx-softness: 0.4;
281
+ evg-fx-shade: 0.45;
282
+ evg-fx-hue: 218;
283
+ evg-fx-tint: 0.25;
284
+ evg-fx-seed: 8;
285
+ }
@@ -0,0 +1,63 @@
1
+ // SPDX-License-Identifier: MIT
2
+ //
3
+ // The preset blocks in `effect-presets.css`, as data.
4
+ //
5
+ // One reader, three callers: `effect-shots.mjs` paints them, `fx-check.mjs`
6
+ // holds each one to producing the effect it names, and the gallery demo's
7
+ // background picker pastes one into the stylesheet it is editing. A second
8
+ // copy of this regex would be a second answer to "what does that file say".
9
+ //
10
+ // NOT A CSS PARSER, and it does not need to be: the file is this repository's
11
+ // own, every block in it is `.name { prop: value; … }`, and the only
12
+ // declarations that matter to a shader are the `evg-fx-*` numbers. The ENGINE
13
+ // parses the same file for real in `fx-check.mjs`, which compares every
14
+ // declaration it read against what came out of here — so this staying simple
15
+ // is checked rather than hoped for.
16
+ //
17
+ // No `fs` here on purpose: the gallery bundle imports this, and a browser has
18
+ // no filesystem. The caller brings the text.
19
+
20
+ /** Every preset block in `src`, as
21
+ * `{ name, kind, trigger, title, params, background, body }`.
22
+ *
23
+ * `kind` is the block's own `evg-surface-effect`, so nothing here knows which
24
+ * effects exist — the presets say. `body` is the block's declarations exactly
25
+ * as written, which is what makes one paste-able. */
26
+ export function parsePresets(src) {
27
+ const out = [];
28
+ for (const m of src.matchAll(/\.((?:sky|fx)-[a-z-]+)\s*\{([^}]*)\}/g)) {
29
+ const params = {};
30
+ let kind = "";
31
+ let trigger = "";
32
+ let background = [0, 0, 0, 1];
33
+ for (const d of m[2].matchAll(/([a-z0-9-]+)\s*:\s*([^;]+);/g)) {
34
+ const name = d[1].trim();
35
+ const value = d[2].trim();
36
+ if (name.startsWith("evg-fx-")) params[name.slice("evg-fx-".length)] = Number(value);
37
+ else if (name === "evg-surface-effect") kind = value;
38
+ else if (name === "evg-effect-on") trigger = value;
39
+ else if (name === "background-color") {
40
+ const rgb = value.match(/-?\d+(\.\d+)?/g).map(Number);
41
+ background = [rgb[0], rgb[1], rgb[2], rgb.length > 3 ? rgb[3] : 1];
42
+ }
43
+ }
44
+ // The comment above the block is its caption; the presets are documented
45
+ // for a reader, so a picture and a menu may as well say the same thing.
46
+ // The LAST comment before the block, not the first one in the file —
47
+ // which is what a match over everything preceding it finds, and it
48
+ // labelled all five pictures with the name of the first.
49
+ const before = src.slice(0, m.index);
50
+ const opened = before.lastIndexOf("/*");
51
+ const note = opened < 0 ? null : before.slice(opened).match(/^\/\*\s*([A-Z][A-Z ']+)\./);
52
+ out.push({
53
+ name: m[1],
54
+ kind,
55
+ trigger,
56
+ title: note ? note[1].toLowerCase() : m[1],
57
+ params,
58
+ background,
59
+ body: m[2].trim(),
60
+ });
61
+ }
62
+ return out;
63
+ }
@@ -0,0 +1,135 @@
1
+ /**
2
+ * The effect presets, painted.
3
+ *
4
+ * node lib/evg/gl/effect-shots.mjs [out.png] [--tile 440x280] [--only plasma]
5
+ *
6
+ * One picture of every preset in `effect-presets.css`, drawn through the real
7
+ * painter with the values that file holds — read out of it rather than
8
+ * repeated here, so a preset somebody changes changes its own picture and a
9
+ * preset nobody can parse fails loudly instead of quietly drawing the default.
10
+ *
11
+ * The reading is `effect-presets.js` — deliberately not a CSS parser, and
12
+ * shared with the gallery demo's background picker so there is one answer to
13
+ * what that file says. The ENGINE's own parser reads it for real in
14
+ * `fx-check.mjs`, which holds every preset to producing the effect it names.
15
+ */
16
+
17
+ import fs from "node:fs";
18
+ import path from "node:path";
19
+ import { fileURLToPath, pathToFileURL } from "node:url";
20
+ import { MissingDomDeps, requireHostTool, findChromium } from "../../../gallery/ui/conformance/dom-adapter.mjs";
21
+ import { parsePresets } from "./effect-presets.js";
22
+
23
+ const HERE = path.dirname(fileURLToPath(import.meta.url));
24
+
25
+ /** Every preset block in `effect-presets.css`, read off disk. The parsing is
26
+ * `effect-presets.js`, which the gallery's background picker imports too —
27
+ * one answer to "what does that file say", in a module with no `fs` in it. */
28
+ export function readPresets(file = path.join(HERE, "effect-presets.css")) {
29
+ return parsePresets(fs.readFileSync(file, "utf8"));
30
+ }
31
+
32
+ const OUT = process.argv[2] && !process.argv[2].startsWith("--")
33
+ ? process.argv[2]
34
+ : path.join(HERE, "effect-presets.png");
35
+ const tileArg = process.argv.indexOf("--tile");
36
+ const [TW, TH] = tileArg > -1 && process.argv[tileArg + 1]
37
+ ? process.argv[tileArg + 1].split("x").map(Number)
38
+ : [440, 280];
39
+
40
+ const onlyAt = process.argv.indexOf("--only");
41
+ const only = onlyAt > -1 ? process.argv[onlyAt + 1] : null;
42
+ const presets = readPresets().filter((p) => !only || p.kind.includes(only) || p.name.includes(only));
43
+ if (presets.length === 0) {
44
+ console.error("no preset blocks found in effect-presets.css" + (only ? ` matching ${only}` : ""));
45
+ process.exit(3);
46
+ }
47
+
48
+ // Two to a row, with a gap, and the name under each.
49
+ const COLS = 2;
50
+ const GAP = 16;
51
+ const LABEL = 30;
52
+ const ROWS = Math.ceil(presets.length / COLS);
53
+ const W = COLS * TW + (COLS + 1) * GAP;
54
+ const H = ROWS * (TH + LABEL) + (ROWS + 1) * GAP;
55
+
56
+ const painter = fs.readFileSync(path.join(HERE, "evg-webgl.js"), "utf8").replace(/^export /gm, "");
57
+
58
+ /** Which layer each registered effect is, read out of the painter rather than
59
+ * listed here. Only one question is asked of it: a BACKDROP effect draws what
60
+ * is BEHIND it, so its tile needs something behind it — over a flat colour a
61
+ * lens is invisible by construction, because the refraction of one colour is
62
+ * that colour. A source effect gets a plain ground, which is what it wants. */
63
+ const LAYER = {};
64
+ for (const m of painter.matchAll(/name:\s*"([a-z-]+)",\s*\n\s*layer:\s*"([a-z]+)"/g)) LAYER[m[1]] = m[2];
65
+
66
+ const cmds = [{ k: 0, x: 0, y: 0, w: W, h: H, c: [10, 11, 18, 1] }];
67
+ const effects = [];
68
+ presets.forEach((p, i) => {
69
+ const col = i % COLS;
70
+ const row = Math.floor(i / COLS);
71
+ const x = GAP + col * (TW + GAP);
72
+ const y = GAP + row * (TH + LABEL + GAP);
73
+ // THE GROUND FIRST, AND THE EFFECT ON A RECTANGLE OF ITS OWN — which is how
74
+ // a page does it, and the only arrangement that works for every layer. A
75
+ // BACKDROP effect runs BEFORE the element's own background, so a preset
76
+ // painted as one opaque rectangle with `efx` on it would have its drops
77
+ // drawn and then covered by the very box that asked for them. Here the
78
+ // colour is the ground, and the effect's own box is transparent — exactly
79
+ // what `.fx-glass` does over the demo's sky.
80
+ cmds.push({ k: 0, x, y, w: TW, h: TH, r: 14, c: p.background });
81
+ if (LAYER[p.kind] === "backdrop") {
82
+ // A page under the glass: a title bar and three lines of body, the shapes
83
+ // whose edges a drop or a pane visibly bends.
84
+ const bars = [[0.06, 0.18, 0.46, 0.075, [120, 142, 212, 1]],
85
+ [0.06, 0.34, 0.80, 0.030, [78, 88, 132, 1]],
86
+ [0.06, 0.44, 0.72, 0.030, [78, 88, 132, 1]],
87
+ [0.06, 0.54, 0.55, 0.030, [78, 88, 132, 1]],
88
+ [0.06, 0.72, 0.88, 0.012, [168, 178, 228, 1]]];
89
+ for (const [bx, by, bw, bh, c] of bars) {
90
+ cmds.push({ k: 0, x: x + TW * bx, y: y + TH * by, w: TW * bw, h: TH * bh, r: 3, c });
91
+ }
92
+ }
93
+ cmds.push({ k: 0, x, y, w: TW, h: TH, r: 14, c: [0, 0, 0, 0], efx: p.name });
94
+ effects.push({ id: p.name, kind: p.kind, on: p.trigger || "always", box: [x, y, TW, TH], r: 14, p: p.params, time: 3.2 });
95
+ cmds.push({
96
+ k: 3, x: x + 2, y: y + TH + 7, w: TW, h: 18,
97
+ c: [150, 158, 196, 1], text: `.${p.name} — ${p.kind} — ${p.title}`, font: "Open Sans", size: 13,
98
+ });
99
+ });
100
+
101
+ const page = `<!doctype html><meta charset="utf-8"><body style="margin:0">
102
+ <canvas id="c" width="${W}" height="${H}"></canvas>
103
+ <script>
104
+ ${painter}
105
+ try {
106
+ const gl = document.getElementById("c").getContext("webgl2", { antialias: true, alpha: false });
107
+ const doc = ${JSON.stringify({ width: W, height: H, cmds, effects })};
108
+ renderDisplayList(gl, { list: { cmds: doc.cmds, effects: doc.effects }, width: doc.width, height: doc.height }, { dpr: 1 });
109
+ } catch (e) { window.__ERR__ = String(e && e.stack || e); }
110
+ window.__DONE__ = true;
111
+ </script></body>`;
112
+
113
+ let chromium;
114
+ try {
115
+ ({ chromium } = requireHostTool("playwright-core"));
116
+ } catch (e) {
117
+ console.error(e instanceof MissingDomDeps ? e.message : String(e));
118
+ process.exit(3);
119
+ }
120
+ const browser = await chromium.launch({
121
+ executablePath: findChromium(),
122
+ args: ["--use-gl=swiftshader", "--enable-unsafe-swiftshader"],
123
+ });
124
+ const tab = await browser.newPage({ viewport: { width: W + 20, height: H + 20 } });
125
+ const tmp = path.join(HERE, ".effect-shots.html");
126
+ fs.writeFileSync(tmp, page);
127
+ await tab.goto(pathToFileURL(tmp).href);
128
+ await tab.waitForFunction("window.__DONE__ === true", { timeout: 30000 });
129
+ const err = await tab.evaluate(() => window.__ERR__ || null);
130
+ if (err) { console.error("painter threw: " + err); process.exit(1); }
131
+ await tab.locator("#c").screenshot({ path: OUT });
132
+ await browser.close();
133
+ fs.rmSync(tmp, { force: true });
134
+ console.log(`${presets.length} presets → ${OUT}`);
135
+ for (const p of presets) console.log(` .${p.name} ${p.kind}`);