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,662 @@
1
+ ; SPDX-License-Identifier: MIT
2
+
3
+ ; ==============================================================================
4
+ ; evg_trace_cli.rgr — bitmap → SVG from a command line
5
+ ; ==============================================================================
6
+ ;
7
+ ; The tracer already runs in a browser and in the test harness. This is the
8
+ ; third caller it needed: a file in, a file out, no page and no Node-only
9
+ ; plumbing, so the same engine can be built for whichever runtime is at hand.
10
+ ; Everything it uses — the PNG and JPEG decoders, the tracer, the SVG writer —
11
+ ; is Ranger, so the compiled program is one self-contained file per target with
12
+ ; no library to install.
13
+ ;
14
+ ; npm run evg:trace:cli -- in.png out.svg --preset broken
15
+ ;
16
+ ; The option names are exactly the fields of EvgTraceOptions, so there is
17
+ ; nothing extra to learn and nothing to keep in sync: --colorCount 12 sets
18
+ ; colorCount. See EvgTraceTypes.rgr for what each one means.
19
+ ;
20
+ ; Numbers are parsed here rather than with to_int, whose string form is
21
+ ; optional-typed and behaves differently per target. A digit loop is the same
22
+ ; everywhere.
23
+ ; ==============================================================================
24
+
25
+ Import "../EvgBitmapTracer.rgr"
26
+ Import "pkg:image/PNGDecoder.rgr"
27
+ Import "pkg:image/JPEGDecoder.rgr"
28
+ Import "pkg:image/ProgressiveJPEGDecoder.rgr"
29
+
30
+ class EvgTraceCli {
31
+
32
+ Constructor () {
33
+ }
34
+
35
+ sfn m@(main):void () {
36
+ def cli (new EvgTraceCli())
37
+ cli.run()
38
+ }
39
+
40
+ ; --- parsing ----------------------------------------------------------
41
+
42
+ sfn digitOf:int (ch:string) {
43
+ return (indexOf "0123456789" ch)
44
+ }
45
+
46
+ sfn parseInt:int (s:string) {
47
+ def n:int (strlen s)
48
+ def i:int 0
49
+ def neg:boolean false
50
+ if (n > 0) {
51
+ def first:string (substring s 0 1)
52
+ if (first == "-") {
53
+ neg = true
54
+ i = 1
55
+ }
56
+ if (first == "+") {
57
+ i = 1
58
+ }
59
+ }
60
+ def v:int 0
61
+ while (i < n) {
62
+ def d:int (EvgTraceCli.digitOf((substring s i (i + 1))))
63
+ if (d < 0) {
64
+ i = n
65
+ } {
66
+ v = ((v * 10) + d)
67
+ i = (i + 1)
68
+ }
69
+ }
70
+ if (neg) {
71
+ return (0 - v)
72
+ }
73
+ return v
74
+ }
75
+
76
+ sfn parseDouble:double (s:string) {
77
+ def n:int (strlen s)
78
+ def i:int 0
79
+ def neg:boolean false
80
+ if (n > 0) {
81
+ def first:string (substring s 0 1)
82
+ if (first == "-") {
83
+ neg = true
84
+ i = 1
85
+ }
86
+ if (first == "+") {
87
+ i = 1
88
+ }
89
+ }
90
+ def whole:double 0.0
91
+ def stop:boolean false
92
+ while ((i < n) && (stop == false)) {
93
+ def ch:string (substring s i (i + 1))
94
+ def d:int (EvgTraceCli.digitOf(ch))
95
+ if (d < 0) {
96
+ stop = true
97
+ } {
98
+ whole = ((whole * 10.0) + (to_double d))
99
+ i = (i + 1)
100
+ }
101
+ }
102
+ if (i < n) {
103
+ def dot:string (substring s i (i + 1))
104
+ if (dot == ".") {
105
+ i = (i + 1)
106
+ def scale:double 1.0
107
+ def more:boolean true
108
+ while ((i < n) && more) {
109
+ def ch2:string (substring s i (i + 1))
110
+ def d2:int (EvgTraceCli.digitOf(ch2))
111
+ if (d2 < 0) {
112
+ more = false
113
+ } {
114
+ scale = (scale / 10.0)
115
+ whole = (whole + ((to_double d2) * scale))
116
+ i = (i + 1)
117
+ }
118
+ }
119
+ }
120
+ }
121
+ if (neg) {
122
+ return (0.0 - whole)
123
+ }
124
+ return whole
125
+ }
126
+
127
+ ; Anything but a plain no is a yes, so `--optcurve 0` and `--optcurve false`
128
+ ; both turn it off and a bare `--optcurve` turns it on.
129
+ sfn parseBool:boolean (s:string) {
130
+ if (s == "0") {
131
+ return false
132
+ }
133
+ if (s == "false") {
134
+ return false
135
+ }
136
+ if (s == "no") {
137
+ return false
138
+ }
139
+ if (s == "off") {
140
+ return false
141
+ }
142
+ return true
143
+ }
144
+
145
+ sfn splitList:[string] (s:string) {
146
+ def out:[string]
147
+ def parts:[string] (strsplit s ",")
148
+ def i:int 0
149
+ while (i < (array_length parts)) {
150
+ def p:string (trim (itemAt parts i))
151
+ if ((strlen p) > 0) {
152
+ push out p
153
+ }
154
+ i = (i + 1)
155
+ }
156
+ return out
157
+ }
158
+
159
+ ; --- paths ------------------------------------------------------------
160
+
161
+ sfn lastSepOf:int (path:string) {
162
+ def a:int (lastIndexOf path "/")
163
+ def b:int (lastIndexOf path "\\")
164
+ if (b > a) {
165
+ return b
166
+ }
167
+ return a
168
+ }
169
+
170
+ sfn dirOf:string (path:string) {
171
+ def sep:int (EvgTraceCli.lastSepOf(path))
172
+ if (sep < 0) {
173
+ return "."
174
+ }
175
+ return (substring path 0 sep)
176
+ }
177
+
178
+ sfn fileOf:string (path:string) {
179
+ def sep:int (EvgTraceCli.lastSepOf(path))
180
+ if (sep < 0) {
181
+ return path
182
+ }
183
+ return (substring path (sep + 1) (strlen path))
184
+ }
185
+
186
+ ; --- options ----------------------------------------------------------
187
+
188
+ ; One name per EvgTraceOptions field. Anything else is a typo, and saying so
189
+ ; is the whole point: a silently ignored --colorcount is an hour lost to
190
+ ; wondering why the palette will not change.
191
+ fn applyOption:boolean (o:EvgTraceOptions name:string value:string) {
192
+ if (name == "turdsize") {
193
+ o.turdsize = (EvgTraceCli.parseInt(value))
194
+ return true
195
+ }
196
+ if (name == "alphamax") {
197
+ o.alphamax = (EvgTraceCli.parseDouble(value))
198
+ return true
199
+ }
200
+ if (name == "turnpolicy") {
201
+ o.turnpolicy = value
202
+ return true
203
+ }
204
+ if (name == "optcurve") {
205
+ o.optcurve = (EvgTraceCli.parseBool(value))
206
+ return true
207
+ }
208
+ if (name == "opttolerance") {
209
+ o.opttolerance = (EvgTraceCli.parseDouble(value))
210
+ return true
211
+ }
212
+ if (name == "threshold") {
213
+ o.threshold = (EvgTraceCli.parseInt(value))
214
+ return true
215
+ }
216
+ if (name == "blackOnWhite") {
217
+ o.blackOnWhite = (EvgTraceCli.parseBool(value))
218
+ return true
219
+ }
220
+ if (name == "fillHex") {
221
+ o.fillHex = value
222
+ return true
223
+ }
224
+ if (name == "colorCount") {
225
+ o.colorCount = (EvgTraceCli.parseInt(value))
226
+ return true
227
+ }
228
+ if (name == "skipLuma") {
229
+ o.skipLuma = (EvgTraceCli.parseInt(value))
230
+ return true
231
+ }
232
+ if (name == "flatTolerance") {
233
+ o.flatTolerance = (EvgTraceCli.parseInt(value))
234
+ return true
235
+ }
236
+ if (name == "edgeSnap") {
237
+ o.edgeSnap = (EvgTraceCli.parseBool(value))
238
+ return true
239
+ }
240
+ if (name == "snapRatio") {
241
+ o.snapRatio = (EvgTraceCli.parseDouble(value))
242
+ return true
243
+ }
244
+ if (name == "lumaWeight") {
245
+ o.lumaWeight = (EvgTraceCli.parseInt(value))
246
+ return true
247
+ }
248
+ if (name == "colorSpace") {
249
+ o.colorSpace = value
250
+ return true
251
+ }
252
+ if (name == "paletteMode") {
253
+ o.paletteMode = value
254
+ return true
255
+ }
256
+ if (name == "paletteHex") {
257
+ o.paletteHex = (EvgTraceCli.splitList(value))
258
+ return true
259
+ }
260
+ if (name == "paletteBias") {
261
+ o.paletteBias = value
262
+ return true
263
+ }
264
+ if (name == "paletteChroma") {
265
+ o.paletteChroma = (EvgTraceCli.parseInt(value))
266
+ return true
267
+ }
268
+ if (name == "paletteMute") {
269
+ o.paletteMute = (EvgTraceCli.parseInt(value))
270
+ return true
271
+ }
272
+ if (name == "paletteTint") {
273
+ o.paletteTint = (EvgTraceCli.parseInt(value))
274
+ return true
275
+ }
276
+ if (name == "paletteWarm") {
277
+ o.paletteWarm = (EvgTraceCli.parseInt(value))
278
+ return true
279
+ }
280
+ if (name == "paletteContrast") {
281
+ o.paletteContrast = (EvgTraceCli.parseInt(value))
282
+ return true
283
+ }
284
+ if (name == "minColorDelta") {
285
+ o.minColorDelta = (EvgTraceCli.parseInt(value))
286
+ return true
287
+ }
288
+ if (name == "contourMode") {
289
+ o.contourMode = value
290
+ return true
291
+ }
292
+ if (name == "overlaySimilar") {
293
+ o.overlaySimilar = (EvgTraceCli.parseInt(value))
294
+ return true
295
+ }
296
+ if (name == "overlayFollowBase") {
297
+ o.overlayFollowBase = (EvgTraceCli.parseBool(value))
298
+ return true
299
+ }
300
+ if (name == "detailSwatches") {
301
+ o.detailSwatches = (EvgTraceCli.parseInt(value))
302
+ return true
303
+ }
304
+ if (name == "detailSpread") {
305
+ o.detailSpread = (EvgTraceCli.parseInt(value))
306
+ return true
307
+ }
308
+ if (name == "detailRadius") {
309
+ o.detailRadius = (EvgTraceCli.parseInt(value))
310
+ return true
311
+ }
312
+ if (name == "detailBoost") {
313
+ o.detailBoost = (EvgTraceCli.parseInt(value))
314
+ return true
315
+ }
316
+ if (name == "detailTrueColor") {
317
+ o.detailTrueColor = (EvgTraceCli.parseBool(value))
318
+ return true
319
+ }
320
+ if (name == "detailColors") {
321
+ o.detailColors = (EvgTraceCli.parseInt(value))
322
+ return true
323
+ }
324
+ if (name == "detailMinShare") {
325
+ o.detailMinShare = (EvgTraceCli.parseInt(value))
326
+ return true
327
+ }
328
+ if (name == "detailColorMerge") {
329
+ o.detailColorMerge = (EvgTraceCli.parseInt(value))
330
+ return true
331
+ }
332
+ if (name == "detailColorMax") {
333
+ o.detailColorMax = (EvgTraceCli.parseInt(value))
334
+ return true
335
+ }
336
+ if (name == "edgeMinRun") {
337
+ o.edgeMinRun = (EvgTraceCli.parseInt(value))
338
+ return true
339
+ }
340
+ if (name == "contourEdge") {
341
+ o.contourEdge = (EvgTraceCli.parseInt(value))
342
+ return true
343
+ }
344
+ if (name == "contourSpread") {
345
+ o.contourSpread = (EvgTraceCli.parseInt(value))
346
+ return true
347
+ }
348
+ if (name == "gradientFill") {
349
+ o.gradientFill = (EvgTraceCli.parseBool(value))
350
+ return true
351
+ }
352
+ if (name == "gradientGain") {
353
+ o.gradientGain = (EvgTraceCli.parseInt(value))
354
+ return true
355
+ }
356
+ if (name == "layerMode") {
357
+ o.layerMode = value
358
+ return true
359
+ }
360
+ if (name == "pathFormat") {
361
+ o.pathFormat = value
362
+ return true
363
+ }
364
+ if (name == "pathPrecision") {
365
+ o.pathPrecision = (EvgTraceCli.parseInt(value))
366
+ return true
367
+ }
368
+ if (name == "smooth") {
369
+ o.smooth = (EvgTraceCli.parseInt(value))
370
+ return true
371
+ }
372
+ if (name == "minRegion") {
373
+ o.minRegion = (EvgTraceCli.parseInt(value))
374
+ return true
375
+ }
376
+ if (name == "absorbContrast") {
377
+ o.absorbContrast = (EvgTraceCli.parseInt(value))
378
+ return true
379
+ }
380
+ if (name == "bgMode") {
381
+ o.bgMode = value
382
+ return true
383
+ }
384
+ if (name == "bgColor") {
385
+ o.bgColor = value
386
+ return true
387
+ }
388
+ if (name == "bgTolerance") {
389
+ o.bgTolerance = (EvgTraceCli.parseInt(value))
390
+ return true
391
+ }
392
+ return false
393
+ }
394
+
395
+ ; Which options are switches. A switch may be written bare, so it must not
396
+ ; swallow the token after it — and the token after it is very often the
397
+ ; output path.
398
+ sfn isSwitch:boolean (name:string) {
399
+ if (name == "optcurve") {
400
+ return true
401
+ }
402
+ if (name == "blackOnWhite") {
403
+ return true
404
+ }
405
+ if (name == "edgeSnap") {
406
+ return true
407
+ }
408
+ if (name == "overlayFollowBase") {
409
+ return true
410
+ }
411
+ if (name == "detailTrueColor") {
412
+ return true
413
+ }
414
+ if (name == "gradientFill") {
415
+ return true
416
+ }
417
+ return false
418
+ }
419
+
420
+ ; Whether a token reads as a value for a switch, as opposed to being the
421
+ ; next thing on the line.
422
+ sfn looksBoolean:boolean (s:string) {
423
+ return ((indexOf "|0|1|true|false|yes|no|on|off|" ("|" + s + "|")) >= 0)
424
+ }
425
+
426
+ fn printUsage:void () {
427
+ print "evg-trace — bitmap to SVG (Ranger EvgBitmapTracer)"
428
+ print ""
429
+ print " evg-trace <input.png|.jpg> <output.svg> [options]"
430
+ print ""
431
+ print " The two paths may come anywhere among the options, and an"
432
+ print " option may be written --name value or --name=value."
433
+ print ""
434
+ print " --preset <name> lineart | poster | photo | print | broken"
435
+ print " --<option> <value>"
436
+ print ""
437
+ print "Options are the fields of EvgTraceOptions, e.g. --colorCount 12"
438
+ print "--paletteMute 130 --pathPrecision 1. See EvgTraceTypes.rgr for"
439
+ print "what each one does and what it defaults to."
440
+ print ""
441
+ print "Known options:"
442
+ print " turdsize alphamax turnpolicy optcurve opttolerance threshold"
443
+ print " blackOnWhite fillHex colorCount skipLuma flatTolerance edgeSnap"
444
+ print " snapRatio lumaWeight colorSpace paletteMode paletteHex"
445
+ print " paletteBias paletteChroma paletteMute paletteTint paletteWarm"
446
+ print " paletteContrast minColorDelta contourMode overlaySimilar"
447
+ print " overlayFollowBase detailSwatches detailSpread detailRadius"
448
+ print " detailBoost detailTrueColor detailColors detailMinShare"
449
+ print " detailColorMerge detailColorMax edgeMinRun contourEdge"
450
+ print " contourSpread gradientFill gradientGain layerMode pathFormat"
451
+ print " pathPrecision smooth minRegion absorbContrast bgMode bgColor"
452
+ print " bgTolerance"
453
+ }
454
+
455
+ ; --- decode -----------------------------------------------------------
456
+
457
+ ; A JPEG says which kind it is in its first SOF marker, which always
458
+ ; precedes the entropy-coded data — so the first 0xFFC0 or 0xFFC2 from the
459
+ ; start is the answer and nothing later can be mistaken for it.
460
+ sfn isProgressiveJpeg:boolean (bytes:buffer) {
461
+ def n:int (buffer_length bytes)
462
+ def i:int 0
463
+ while (i < (n - 1)) {
464
+ def b:int (buffer_get bytes i)
465
+ if (b == 255) {
466
+ def marker:int (buffer_get bytes (i + 1))
467
+ ; 194 = SOF2 (progressive), 192/193 = SOF0/1 (baseline)
468
+ if (marker == 194) {
469
+ return true
470
+ }
471
+ if (marker == 192) {
472
+ return false
473
+ }
474
+ if (marker == 193) {
475
+ return false
476
+ }
477
+ }
478
+ i = (i + 1)
479
+ }
480
+ return false
481
+ }
482
+
483
+ ; By the magic bytes rather than the extension: a .png that is really a
484
+ ; JPEG is common enough, and the extension is the one thing about a file
485
+ ; that nothing checks. The decoders report failure as a 1x1 image, which
486
+ ; the caller checks for.
487
+ fn decodeImage:ImageBuffer (bytes:buffer dir:string file:string) {
488
+ def n:int (buffer_length bytes)
489
+ def fail (new ImageBuffer())
490
+ fail.init(1 1)
491
+ if (n < 4) {
492
+ return fail
493
+ }
494
+ def b0:int (buffer_get bytes 0)
495
+ def b1:int (buffer_get bytes 1)
496
+ if ((b0 == 137) && (b1 == 80)) {
497
+ def png (new PNGDecoder())
498
+ return (png.decodeBytes(bytes))
499
+ }
500
+ if ((b0 == 255) && (b1 == 216)) {
501
+ if (EvgTraceCli.isProgressiveJpeg(bytes)) {
502
+ ; The progressive decoder reads the file itself; it has no
503
+ ; in-memory entry point.
504
+ def prog (new ProgressiveJPEGDecoder())
505
+ return (prog.decode(dir file))
506
+ }
507
+ def jpg (new JPEGDecoder())
508
+ jpg.quiet = true
509
+ return (jpg.decodeBytes(bytes))
510
+ }
511
+ return fail
512
+ }
513
+
514
+ ; --- run --------------------------------------------------------------
515
+
516
+ fn run:void () {
517
+ def argCount:int (shell_arg_cnt)
518
+ if (argCount < 1) {
519
+ this.printUsage()
520
+ return
521
+ }
522
+
523
+ ; Positionals are taken wherever they fall. Requiring them first is the
524
+ ; one thing about a command line nobody remembers, and
525
+ ; `in.jpg --colorCount 4 out.svg` reading `--colorCount` as the output
526
+ ; path is a confusing way to say so.
527
+ def opts:EvgTraceOptions (EvgTraceOptions.defaults())
528
+ def positional:[string]
529
+ def i:int 0
530
+ def bad:boolean false
531
+ def wantHelp:boolean false
532
+ while (i < argCount) {
533
+ def arg:string (shell_arg i)
534
+ if ((arg == "-h") || (arg == "--help")) {
535
+ wantHelp = true
536
+ } {
537
+ if ((indexOf arg "--") == 0) {
538
+ def body:string (substring arg 2 (strlen arg))
539
+ def name:string body
540
+ def value:string ""
541
+ def haveValue:boolean false
542
+ ; --name=value is accepted as well as --name value.
543
+ def eq:int (indexOf body "=")
544
+ if (eq >= 0) {
545
+ name = (substring body 0 eq)
546
+ value = (substring body (eq + 1) (strlen body))
547
+ haveValue = true
548
+ }
549
+ def isFlag:boolean (EvgTraceCli.isSwitch(name))
550
+ if (haveValue == false) {
551
+ if ((i + 1) < argCount) {
552
+ def peek:string (shell_arg (i + 1))
553
+ def peekIsOption:boolean ((indexOf peek "--") == 0)
554
+ def take:boolean false
555
+ if (peekIsOption == false) {
556
+ take = true
557
+ if (isFlag) {
558
+ ; A switch only eats what reads as a switch
559
+ ; value; anything else is a positional.
560
+ take = (EvgTraceCli.looksBoolean(peek))
561
+ }
562
+ }
563
+ if (take) {
564
+ value = peek
565
+ haveValue = true
566
+ i = (i + 1)
567
+ }
568
+ }
569
+ }
570
+ if ((haveValue == false) && isFlag) {
571
+ value = "true"
572
+ haveValue = true
573
+ }
574
+ if (haveValue == false) {
575
+ print (("--" + name) + " needs a value")
576
+ bad = true
577
+ } {
578
+ if (name == "preset") {
579
+ opts = (EvgTraceOptions.preset(value))
580
+ } {
581
+ def ok:boolean (this.applyOption(opts name value))
582
+ if (ok == false) {
583
+ print ("unknown option --" + name)
584
+ bad = true
585
+ }
586
+ }
587
+ }
588
+ } {
589
+ push positional arg
590
+ }
591
+ }
592
+ i = (i + 1)
593
+ }
594
+
595
+ if (wantHelp) {
596
+ this.printUsage()
597
+ return
598
+ }
599
+ def pn:int (array_length positional)
600
+ if (pn > 2) {
601
+ print (("expected an input and an output path, got " + (to_string pn)) + ":")
602
+ def pi:int 0
603
+ while (pi < pn) {
604
+ print (" " + (itemAt positional pi))
605
+ pi = (pi + 1)
606
+ }
607
+ bad = true
608
+ }
609
+ if (pn < 2) {
610
+ if (bad == false) {
611
+ print "an input path and an output path are both needed"
612
+ }
613
+ bad = true
614
+ }
615
+ if (bad) {
616
+ print ""
617
+ this.printUsage()
618
+ return
619
+ }
620
+ def inputPath:string (itemAt positional 0)
621
+ def outputPath:string (itemAt positional 1)
622
+
623
+ def inDir:string (EvgTraceCli.dirOf(inputPath))
624
+ def inFile:string (EvgTraceCli.fileOf(inputPath))
625
+ ; Asked for a file that is not there, buffer_read_file raises on some
626
+ ; targets and returns nothing on others. Neither is a message, so look
627
+ ; first: a mistyped path is the most ordinary thing that can happen
628
+ ; here and it should read as one line, not as a stack trace.
629
+ if ((file_exists inDir inFile) == false) {
630
+ print ("no such file: " + inputPath)
631
+ return
632
+ }
633
+ def bytes:buffer (buffer_read_file inDir inFile)
634
+ if ((buffer_length bytes) == 0) {
635
+ print ("cannot read " + inputPath)
636
+ return
637
+ }
638
+ def img:ImageBuffer (this.decodeImage(bytes inDir inFile))
639
+ ; 1x1 is how both decoders report a failure, and writing an SVG of it
640
+ ; would be worse than saying so: the file would look like a result.
641
+ if (((img.width) < 2) && ((img.height) < 2)) {
642
+ print ("not a PNG or JPEG this build can decode: " + inputPath)
643
+ return
644
+ }
645
+
646
+ def tr:EvgBitmapTracer (EvgBitmapTracer.fromImageBuffer(img opts))
647
+ tr.trace()
648
+ def svg:string (tr.toSVG())
649
+
650
+ def outDir:string (EvgTraceCli.dirOf(outputPath))
651
+ def outFile:string (EvgTraceCli.fileOf(outputPath))
652
+ write_file outDir outFile svg
653
+
654
+ def w:string (to_string (img.width))
655
+ def h:string (to_string (img.height))
656
+ def layers:string (to_string (tr.layerCount()))
657
+ def rings:string (to_string (tr.ringCount()))
658
+ def bytesOut:string (to_string (strlen svg))
659
+ print ((((((((outputPath + " ") + w) + "x") + h) + " layers=") + layers) + " rings=") + rings)
660
+ print ((" " + bytesOut) + " bytes")
661
+ }
662
+ }