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,700 @@
1
+ ; SPDX-License-Identifier: MIT
2
+
3
+ ; EVGColor.rgr - Color parsing and manipulation for EVG layout
4
+ ; Supports: hex (#RGB, #RRGGBB, #RRGGBBAA), rgb(), rgba(), hsl(), named colors
5
+
6
+ ; The two colours every element starts with, shared the way the unset unit
7
+ ; is (see EVGUnitDefaults). An EVGColor has no in-place mutator at all — every
8
+ ; operation returns a new colour — so sharing needs no guard beyond the
9
+ ; convention that a field is REPLACED, never written through.
10
+ class EVGColorDefaults @singleton(true) {
11
+ def noColor:EVGColor (new EVGColor())
12
+ def black:EVGColor (new EVGColor())
13
+ Constructor () {
14
+ noColor.isSet = false
15
+ }
16
+ }
17
+
18
+ class EVGColor {
19
+ def r:double 0.0
20
+ def g:double 0.0
21
+ def b:double 0.0
22
+ def a:double 1.0
23
+ def isSet:boolean true
24
+
25
+ Constructor () {
26
+ r = 0.0
27
+ g = 0.0
28
+ b = 0.0
29
+ a = 1.0
30
+ isSet = true
31
+ }
32
+
33
+ sfn create:EVGColor (red:double green:double blue:double alpha:double) {
34
+ def c (new EVGColor())
35
+ c.r = red
36
+ c.g = green
37
+ c.b = blue
38
+ c.a = alpha
39
+ c.isSet = true
40
+ return c
41
+ }
42
+
43
+ sfn rgb:EVGColor (red:int green:int blue:int) {
44
+ return (EVGColor.create((to_double red) (to_double green) (to_double blue) 1.0))
45
+ }
46
+
47
+ sfn rgba:EVGColor (red:int green:int blue:int alpha:double) {
48
+ return (EVGColor.create((to_double red) (to_double green) (to_double blue) alpha))
49
+ }
50
+
51
+ ; The shared "no colour". Read-only by convention — see EVGColorDefaults.
52
+ sfn noColor:EVGColor () {
53
+ return ((EVGColorDefaults.__singleton()).noColor)
54
+ }
55
+
56
+ ; Shared, like noColor.
57
+ sfn black:EVGColor () {
58
+ return ((EVGColorDefaults.__singleton()).black)
59
+ }
60
+
61
+ sfn white:EVGColor () {
62
+ return (EVGColor.rgb(255 255 255))
63
+ }
64
+
65
+ sfn transparent:EVGColor () {
66
+ return (EVGColor.rgba(0 0 0 0.0))
67
+ }
68
+
69
+ ; Parse hex digit to int (0-15)
70
+ sfn hexDigit:int (ch:int) {
71
+ ; '0'-'9' = 48-57
72
+ if ((ch >= 48) && (ch <= 57)) {
73
+ return (ch - 48)
74
+ }
75
+ ; 'A'-'F' = 65-70
76
+ if ((ch >= 65) && (ch <= 70)) {
77
+ return ((ch - 65) + 10)
78
+ }
79
+ ; 'a'-'f' = 97-102
80
+ if ((ch >= 97) && (ch <= 102)) {
81
+ return ((ch - 97) + 10)
82
+ }
83
+ return 0
84
+ }
85
+
86
+ sfn parseHex:EVGColor (hex:string) {
87
+ def c (new EVGColor())
88
+ def len:int (strlen hex)
89
+ def start:int 0
90
+
91
+ ; Skip # if present
92
+ if (len > 0) {
93
+ def firstChar:int (charAt hex 0)
94
+ if (firstChar == 35) { ; '#'
95
+ start = 1
96
+ len = len - 1
97
+ }
98
+ }
99
+
100
+ ; #RGB (3 digits)
101
+ if (len == 3) {
102
+ def r1:int (EVGColor.hexDigit((charAt hex start)))
103
+ def g1:int (EVGColor.hexDigit((charAt hex (start + 1))))
104
+ def b1:int (EVGColor.hexDigit((charAt hex (start + 2))))
105
+ c.r = (to_double ((r1 * 16) + r1))
106
+ c.g = (to_double ((g1 * 16) + g1))
107
+ c.b = (to_double ((b1 * 16) + b1))
108
+ c.a = 1.0
109
+ c.isSet = true
110
+ return c
111
+ }
112
+
113
+ ; #RGBA (4 digits)
114
+ ;
115
+ ; The short form with an alpha. It was simply missing — `#0f08` fell
116
+ ; through every branch and came back unset, which the caller reads as
117
+ ; black at full opacity: a translucent green arriving as opaque black
118
+ ; is about the worst way for a parser to fail.
119
+ if (len == 4) {
120
+ def r4:int (EVGColor.hexDigit((charAt hex start)))
121
+ def g4:int (EVGColor.hexDigit((charAt hex (start + 1))))
122
+ def b4:int (EVGColor.hexDigit((charAt hex (start + 2))))
123
+ def a4:int (EVGColor.hexDigit((charAt hex (start + 3))))
124
+ c.r = (to_double ((r4 * 16) + r4))
125
+ c.g = (to_double ((g4 * 16) + g4))
126
+ c.b = (to_double ((b4 * 16) + b4))
127
+ c.a = ((to_double ((a4 * 16) + a4)) / 255.0)
128
+ c.isSet = true
129
+ return c
130
+ }
131
+
132
+ ; #RRGGBB (6 digits)
133
+ if (len == 6) {
134
+ def r1:int (EVGColor.hexDigit((charAt hex start)))
135
+ def r2:int (EVGColor.hexDigit((charAt hex (start + 1))))
136
+ def g1:int (EVGColor.hexDigit((charAt hex (start + 2))))
137
+ def g2:int (EVGColor.hexDigit((charAt hex (start + 3))))
138
+ def b1:int (EVGColor.hexDigit((charAt hex (start + 4))))
139
+ def b2:int (EVGColor.hexDigit((charAt hex (start + 5))))
140
+ c.r = (to_double ((r1 * 16) + r2))
141
+ c.g = (to_double ((g1 * 16) + g2))
142
+ c.b = (to_double ((b1 * 16) + b2))
143
+ c.a = 1.0
144
+ c.isSet = true
145
+ return c
146
+ }
147
+
148
+ ; #RRGGBBAA (8 digits)
149
+ if (len == 8) {
150
+ def r1:int (EVGColor.hexDigit((charAt hex start)))
151
+ def r2:int (EVGColor.hexDigit((charAt hex (start + 1))))
152
+ def g1:int (EVGColor.hexDigit((charAt hex (start + 2))))
153
+ def g2:int (EVGColor.hexDigit((charAt hex (start + 3))))
154
+ def b1:int (EVGColor.hexDigit((charAt hex (start + 4))))
155
+ def b2:int (EVGColor.hexDigit((charAt hex (start + 5))))
156
+ def a1:int (EVGColor.hexDigit((charAt hex (start + 6))))
157
+ def a2:int (EVGColor.hexDigit((charAt hex (start + 7))))
158
+ c.r = (to_double ((r1 * 16) + r2))
159
+ c.g = (to_double ((g1 * 16) + g2))
160
+ c.b = (to_double ((b1 * 16) + b2))
161
+ c.a = ((to_double ((a1 * 16) + a2)) / 255.0)
162
+ c.isSet = true
163
+ return c
164
+ }
165
+
166
+ c.isSet = false
167
+ return c
168
+ }
169
+
170
+ ; One channel of an HSL colour, from the two endpoints and a position on
171
+ ; the wheel, IN SIXTHS — 0 to 6 rather than 0 to 1.
172
+ ;
173
+ ; Sixths because that is the form a caller can produce exactly, and the
174
+ ; textbook form cannot. Written the usual way this compares `t` against
175
+ ; `1/6`, `1/2` and `2/3` and then computes `(2/3 - t) * 6`, and none of
176
+ ; those constants is representable in binary: at the seam where `t` is
177
+ ; exactly a half, `2/3 - 0.5` comes out a hair under a sixth, times six is
178
+ ; 0.9999999999999998, and the channel lands on 127.49999999999997 instead
179
+ ; of 127.5 — one count below where it belongs. Turning the hue into a
180
+ ; fraction and adding a third, `h/360 + 1/3`, goes wrong the same way at
181
+ ; 270 degrees.
182
+ ;
183
+ ; Dividing the DEGREES by 60 gives whole and half sixths for every hue
184
+ ; anybody types, every boundary here is a whole number, and the channel
185
+ ; offset becomes a plain `+ 2`. Measured against the browser over 131
186
+ ; `hsl()` colours: nine were wrong before this, all of them on a seam, and
187
+ ; those are exactly the colours somebody enters by hand.
188
+ sfn hue6:double (p:double q:double t6in:double) {
189
+ def t6:double t6in
190
+ while (t6 < 0.0) {
191
+ t6 = (t6 + 6.0)
192
+ }
193
+ while (t6 >= 6.0) {
194
+ t6 = (t6 - 6.0)
195
+ }
196
+ if (t6 < 1.0) {
197
+ return (p + ((q - p) * t6))
198
+ }
199
+ if (t6 < 3.0) {
200
+ return q
201
+ }
202
+ if (t6 < 4.0) {
203
+ return (p + ((q - p) * (4.0 - t6)))
204
+ }
205
+ return p
206
+ }
207
+
208
+ ; The same thing taking a fraction of the wheel, 0 to 1. Kept because it
209
+ ; is the shape every reference writes this in and somebody will reach for
210
+ ; it; `hslToRgb` uses `hue6` instead, for the reason above.
211
+ sfn hue2rgb:double (p:double q:double tt:double) {
212
+ def t:double tt
213
+ if (t < 0.0) {
214
+ t = t + 1.0
215
+ }
216
+ if (t > 1.0) {
217
+ t = t - 1.0
218
+ }
219
+ def t6:double (t * 6.0)
220
+ if (t6 < 1.0) {
221
+ return (p + ((q - p) * t6))
222
+ }
223
+ if (t6 < 3.0) {
224
+ return q
225
+ }
226
+ if (t6 < 4.0) {
227
+ return (p + ((q - p) * (4.0 - t6)))
228
+ }
229
+ return p
230
+ }
231
+
232
+ sfn hslToRgb:EVGColor (h:double s:double l:double) {
233
+ ; h = hue (0-360), s = saturation (0-100), l = lightness (0-100)
234
+ def c (new EVGColor())
235
+ def hNorm:double (h / 360.0)
236
+ def sNorm:double (s / 100.0)
237
+ def lNorm:double (l / 100.0)
238
+
239
+ if (sNorm == 0.0) {
240
+ ; Achromatic (gray)
241
+ def gray:double (lNorm * 255.0)
242
+ c.r = gray
243
+ c.g = gray
244
+ c.b = gray
245
+ } {
246
+ def q:double 0.0
247
+ if (lNorm < 0.5) {
248
+ q = (lNorm * (1.0 + sNorm))
249
+ } {
250
+ q = (lNorm + sNorm - (lNorm * sNorm))
251
+ }
252
+ def p:double ((2.0 * lNorm) - q)
253
+ ; In sixths of the wheel, from the degrees, so every boundary is
254
+ ; a whole number and no constant has to be approximated.
255
+ def h6:double (h / 60.0)
256
+ c.r = ((EVGColor.hue6(p q (h6 + 2.0))) * 255.0)
257
+ c.g = ((EVGColor.hue6(p q h6)) * 255.0)
258
+ c.b = ((EVGColor.hue6(p q (h6 - 2.0))) * 255.0)
259
+ }
260
+
261
+ c.a = 1.0
262
+ c.isSet = true
263
+ return c
264
+ }
265
+
266
+ sfn parseNumber:double (str:string) {
267
+ ; Parse a number, handling potential whitespace
268
+ def val@(optional):double (to_double (trim str))
269
+ return (unwrap val)
270
+ }
271
+
272
+ sfn parse:EVGColor (str:string) {
273
+ ; Parse color string in various formats
274
+ def trimmed:string (trim str)
275
+ def len:int (strlen trimmed)
276
+
277
+ if (len == 0) {
278
+ return (EVGColor.noColor())
279
+ }
280
+
281
+ ; Check for hex color
282
+ def firstChar:int (charAt trimmed 0)
283
+ if (firstChar == 35) { ; '#'
284
+ return (EVGColor.parseHex(trimmed))
285
+ }
286
+
287
+ ; Check for rgb()/rgba()
288
+ if (len >= 4) {
289
+ def prefix:string (substring trimmed 0 4)
290
+ if (prefix == "rgba") {
291
+ return (EVGColor.parseRgba(trimmed))
292
+ }
293
+ def prefix3:string (substring trimmed 0 3)
294
+ if (prefix3 == "rgb") {
295
+ return (EVGColor.parseRgb(trimmed))
296
+ }
297
+ if (prefix3 == "hsl") {
298
+ return (EVGColor.parseHsl(trimmed))
299
+ }
300
+ }
301
+
302
+ ; Try named color
303
+ return (EVGColor.parseNamed(trimmed))
304
+ }
305
+
306
+ sfn parseRgb:EVGColor (str:string) {
307
+ ; Parse rgb(r, g, b) or rgb(r g b)
308
+ def c (new EVGColor())
309
+ def len:int (strlen str)
310
+
311
+ ; Find opening paren
312
+ def start:int 0
313
+ def i:int 0
314
+ while (i < len) {
315
+ def ch:int (charAt str i)
316
+ if (ch == 40) { ; '('
317
+ start = i + 1
318
+ }
319
+ i = i + 1
320
+ }
321
+
322
+ ; Extract content between parens
323
+ def end:int (len - 1)
324
+ i = len - 1
325
+ while (i >= 0) {
326
+ def ch:int (charAt str i)
327
+ if (ch == 41) { ; ')'
328
+ end = i
329
+ }
330
+ i = i - 1
331
+ }
332
+
333
+ def content:string (substring str start end)
334
+
335
+ ; Split by comma or space
336
+ def parts:[string]
337
+ def current:string ""
338
+ i = 0
339
+ def contentLen:int (strlen content)
340
+ while (i < contentLen) {
341
+ def ch:int (charAt content i)
342
+ if ((ch == 44) || (ch == 32)) { ; ',' or space
343
+ def trimPart:string (trim current)
344
+ if ((strlen trimPart) > 0) {
345
+ push parts trimPart
346
+ }
347
+ current = ""
348
+ } {
349
+ current = (current + (strfromcode ch))
350
+ }
351
+ i = i + 1
352
+ }
353
+ def trimPart:string (trim current)
354
+ if ((strlen trimPart) > 0) {
355
+ push parts trimPart
356
+ }
357
+
358
+ if ((array_length parts) >= 3) {
359
+ c.r = (EVGColor.parseNumber((itemAt parts 0)))
360
+ c.g = (EVGColor.parseNumber((itemAt parts 1)))
361
+ c.b = (EVGColor.parseNumber((itemAt parts 2)))
362
+ c.a = 1.0
363
+ c.isSet = true
364
+ }
365
+
366
+ return c
367
+ }
368
+
369
+ sfn parseRgba:EVGColor (str:string) {
370
+ ; Parse rgba(r, g, b, a)
371
+ def c:EVGColor (EVGColor.parseRgb(str))
372
+ def len:int (strlen str)
373
+
374
+ ; Find content between parens
375
+ def start:int 0
376
+ def end:int (len - 1)
377
+ def i:int 0
378
+ while (i < len) {
379
+ def ch:int (charAt str i)
380
+ if (ch == 40) {
381
+ start = i + 1
382
+ }
383
+ if (ch == 41) {
384
+ end = i
385
+ }
386
+ i = i + 1
387
+ }
388
+
389
+ def content:string (substring str start end)
390
+
391
+ ; Split and get alpha
392
+ def parts:[string]
393
+ def current:string ""
394
+ i = 0
395
+ def contentLen:int (strlen content)
396
+ while (i < contentLen) {
397
+ def ch:int (charAt content i)
398
+ if ((ch == 44) || (ch == 32)) {
399
+ def trimPart:string (trim current)
400
+ if ((strlen trimPart) > 0) {
401
+ push parts trimPart
402
+ }
403
+ current = ""
404
+ } {
405
+ current = (current + (strfromcode ch))
406
+ }
407
+ i = i + 1
408
+ }
409
+ def trimPart:string (trim current)
410
+ if ((strlen trimPart) > 0) {
411
+ push parts trimPart
412
+ }
413
+
414
+ if ((array_length parts) >= 4) {
415
+ c.r = (EVGColor.parseNumber((itemAt parts 0)))
416
+ c.g = (EVGColor.parseNumber((itemAt parts 1)))
417
+ c.b = (EVGColor.parseNumber((itemAt parts 2)))
418
+ c.a = (EVGColor.parseNumber((itemAt parts 3)))
419
+ c.isSet = true
420
+ }
421
+
422
+ return c
423
+ }
424
+
425
+ sfn parseHsl:EVGColor (str:string) {
426
+ ; Parse hsl(h, s%, l%) or hsla(h, s%, l%, a)
427
+ def len:int (strlen str)
428
+ def start:int 0
429
+ def end:int (len - 1)
430
+ def i:int 0
431
+ while (i < len) {
432
+ def ch:int (charAt str i)
433
+ if (ch == 40) {
434
+ start = i + 1
435
+ }
436
+ if (ch == 41) {
437
+ end = i
438
+ }
439
+ i = i + 1
440
+ }
441
+
442
+ def content:string (substring str start end)
443
+
444
+ ; Split by comma or space
445
+ def parts:[string]
446
+ def current:string ""
447
+ i = 0
448
+ def contentLen:int (strlen content)
449
+ while (i < contentLen) {
450
+ def ch:int (charAt content i)
451
+ if ((ch == 44) || (ch == 32)) {
452
+ def trimPart:string (trim current)
453
+ if ((strlen trimPart) > 0) {
454
+ push parts trimPart
455
+ }
456
+ current = ""
457
+ } {
458
+ current = (current + (strfromcode ch))
459
+ }
460
+ i = i + 1
461
+ }
462
+ def trimPart:string (trim current)
463
+ if ((strlen trimPart) > 0) {
464
+ push parts trimPart
465
+ }
466
+
467
+ if ((array_length parts) >= 3) {
468
+ def h:double (EVGColor.parseNumber((itemAt parts 0)))
469
+ def s:double (EVGColor.parseNumber((itemAt parts 1)))
470
+ def l:double (EVGColor.parseNumber((itemAt parts 2)))
471
+ def c:EVGColor (EVGColor.hslToRgb(h s l))
472
+ if ((array_length parts) >= 4) {
473
+ c.a = (EVGColor.parseNumber((itemAt parts 3)))
474
+ }
475
+ return c
476
+ }
477
+
478
+ return (EVGColor.noColor())
479
+ }
480
+
481
+ sfn parseNamed:EVGColor (name:string) {
482
+ ; Parse named colors (common CSS colors)
483
+ ; Manual lowercase since 'lowercase' operator not available
484
+ def lower:string ""
485
+ def len:int (strlen name)
486
+ def i:int 0
487
+ while (i < len) {
488
+ def ch:int (charAt name i)
489
+ ; A-Z is 65-90, convert to lowercase by adding 32
490
+ if ((ch >= 65) && (ch <= 90)) {
491
+ lower = (lower + (strfromcode (ch + 32)))
492
+ } {
493
+ lower = (lower + (strfromcode ch))
494
+ }
495
+ i = i + 1
496
+ }
497
+
498
+ if (lower == "black") {
499
+ return (EVGColor.rgb(0 0 0))
500
+ }
501
+ if (lower == "white") {
502
+ return (EVGColor.rgb(255 255 255))
503
+ }
504
+ if (lower == "red") {
505
+ return (EVGColor.rgb(255 0 0))
506
+ }
507
+ if (lower == "green") {
508
+ return (EVGColor.rgb(0 128 0))
509
+ }
510
+ if (lower == "blue") {
511
+ return (EVGColor.rgb(0 0 255))
512
+ }
513
+ if (lower == "yellow") {
514
+ return (EVGColor.rgb(255 255 0))
515
+ }
516
+ if (lower == "cyan") {
517
+ return (EVGColor.rgb(0 255 255))
518
+ }
519
+ if (lower == "magenta") {
520
+ return (EVGColor.rgb(255 0 255))
521
+ }
522
+ if (lower == "gray") {
523
+ return (EVGColor.rgb(128 128 128))
524
+ }
525
+ if (lower == "grey") {
526
+ return (EVGColor.rgb(128 128 128))
527
+ }
528
+ if (lower == "orange") {
529
+ return (EVGColor.rgb(255 165 0))
530
+ }
531
+ if (lower == "purple") {
532
+ return (EVGColor.rgb(128 0 128))
533
+ }
534
+ if (lower == "pink") {
535
+ return (EVGColor.rgb(255 192 203))
536
+ }
537
+ if (lower == "brown") {
538
+ return (EVGColor.rgb(165 42 42))
539
+ }
540
+ ; The rest of the sixteen HTML 4 / CSS 2.1 names. The table above had
541
+ ; eleven of them and stopped, so `navy` — which is what somebody
542
+ ; writing a corporate deck reaches for first — parsed as no colour at
543
+ ; all and painted nothing. Completing the standard set is a line worth
544
+ ; drawing; the other 130-odd CSS names are not, and a program that
545
+ ; wants `rebeccapurple` can write the hex.
546
+ if (lower == "navy") {
547
+ return (EVGColor.rgb(0 0 128))
548
+ }
549
+ if (lower == "teal") {
550
+ return (EVGColor.rgb(0 128 128))
551
+ }
552
+ if (lower == "olive") {
553
+ return (EVGColor.rgb(128 128 0))
554
+ }
555
+ if (lower == "maroon") {
556
+ return (EVGColor.rgb(128 0 0))
557
+ }
558
+ if (lower == "silver") {
559
+ return (EVGColor.rgb(192 192 192))
560
+ }
561
+ if (lower == "lime") {
562
+ return (EVGColor.rgb(0 255 0))
563
+ }
564
+ if (lower == "aqua") {
565
+ return (EVGColor.rgb(0 255 255))
566
+ }
567
+ if (lower == "fuchsia") {
568
+ return (EVGColor.rgb(255 0 255))
569
+ }
570
+ if (lower == "transparent") {
571
+ return (EVGColor.transparent())
572
+ }
573
+ if (lower == "none") {
574
+ return (EVGColor.noColor())
575
+ }
576
+
577
+ ; Unknown color
578
+ return (EVGColor.noColor())
579
+ }
580
+
581
+ ; --- a channel, as a byte -------------------------------------------------
582
+ ;
583
+ ; ROUNDED, not truncated. A channel is kept as a double because that is
584
+ ; what every computation produces — an `hsl()` resolution, a gradient stop,
585
+ ; a blend — and truncating on the way out loses most of a bit.
586
+ ;
587
+ ; It is not a rounding nicety. Measured against the browser over 131
588
+ ; `hsl()` colours, truncation got 68 of them wrong: `hsl(0 50% 50%)` came
589
+ ; out 191,63,63 where every browser says 191,64,64, because 0.25 * 255 is
590
+ ; 63.75 and the floor of that is not the nearest byte to it. Over half the
591
+ ; colour wheel was a shade dark, consistently, in a direction nobody would
592
+ ; notice by looking and every screenshot comparison would.
593
+ ;
594
+ ; A colour built from integers — `EVGColor.rgb(59 114 196)` — is unaffected
595
+ ; either way, which is why this survived: the literals in the source were
596
+ ; always right and only the computed colours were wrong.
597
+ fn red:int () {
598
+ if (r > 255.0) {
599
+ return 255
600
+ }
601
+ if (r < 0.0) {
602
+ return 0
603
+ }
604
+ return (to_int (r + 0.5))
605
+ }
606
+
607
+ fn green:int () {
608
+ if (g > 255.0) {
609
+ return 255
610
+ }
611
+ if (g < 0.0) {
612
+ return 0
613
+ }
614
+ return (to_int (g + 0.5))
615
+ }
616
+
617
+ fn blue:int () {
618
+ if (b > 255.0) {
619
+ return 255
620
+ }
621
+ if (b < 0.0) {
622
+ return 0
623
+ }
624
+ return (to_int (b + 0.5))
625
+ }
626
+
627
+ fn alpha:double () {
628
+ if (a < 0.0) {
629
+ return 0.0
630
+ }
631
+ if (a > 1.0) {
632
+ return 1.0
633
+ }
634
+ return a
635
+ }
636
+
637
+ fn toCSSString:string () {
638
+ if (isSet == false) {
639
+ return "none"
640
+ }
641
+ if (a < 1.0) {
642
+ return ("rgba(" + (to_string (this.red())) + "," + (to_string (this.green())) + "," + (to_string (this.blue())) + "," + (to_string (this.alpha())) + ")")
643
+ }
644
+ return ("rgb(" + (to_string (this.red())) + "," + (to_string (this.green())) + "," + (to_string (this.blue())) + ")")
645
+ }
646
+
647
+ fn toHexString:string () {
648
+ if (isSet == false) {
649
+ return "none"
650
+ }
651
+ ; Simple hex output (no alpha)
652
+ def hexChars:string "0123456789ABCDEF"
653
+ def rH:int (this.red())
654
+ def gH:int (this.green())
655
+ def bH:int (this.blue())
656
+
657
+ def r1D:double ((to_double rH) / 16.0)
658
+ def r1:int (to_int r1D)
659
+ def r2:int (rH % 16)
660
+ def g1D:double ((to_double gH) / 16.0)
661
+ def g1:int (to_int g1D)
662
+ def g2:int (gH % 16)
663
+ def b1D:double ((to_double bH) / 16.0)
664
+ def b1:int (to_int b1D)
665
+ def b2:int (bH % 16)
666
+
667
+ return ("#" + (strfromcode (charAt hexChars r1)) + (strfromcode (charAt hexChars r2)) + (strfromcode (charAt hexChars g1)) + (strfromcode (charAt hexChars g2)) + (strfromcode (charAt hexChars b1)) + (strfromcode (charAt hexChars b2)))
668
+ }
669
+
670
+ fn toPDFColorString:string () {
671
+ ; PDF color values are 0-1 range
672
+ if (isSet == false) {
673
+ return ""
674
+ }
675
+ def rN:double (r / 255.0)
676
+ def gN:double (g / 255.0)
677
+ def bN:double (b / 255.0)
678
+ return ((to_string rN) + " " + (to_string gN) + " " + (to_string bN))
679
+ }
680
+
681
+ fn withAlpha:EVGColor (newAlpha:double) {
682
+ return (EVGColor.create(r g b newAlpha))
683
+ }
684
+
685
+ fn lighten:EVGColor (amount:double) {
686
+ ; Lighten color by amount (0-1)
687
+ def newR:double (r + ((255.0 - r) * amount))
688
+ def newG:double (g + ((255.0 - g) * amount))
689
+ def newB:double (b + ((255.0 - b) * amount))
690
+ return (EVGColor.create(newR newG newB a))
691
+ }
692
+
693
+ fn darken:EVGColor (amount:double) {
694
+ ; Darken color by amount (0-1)
695
+ def newR:double (r * (1.0 - amount))
696
+ def newG:double (g * (1.0 - amount))
697
+ def newB:double (b * (1.0 - amount))
698
+ return (EVGColor.create(newR newG newB a))
699
+ }
700
+ }