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.
- package/CHANGELOG.md +1064 -20
- package/LICENSE +3 -1
- package/README.md +123 -28
- package/dist/Lang.rgr +1188 -290
- package/dist/api.d.ts +2343 -879
- package/dist/api.js +79923 -56921
- package/dist/lib/JSON.rgr +102 -91
- package/dist/lib/Shell.rgr +4 -4
- package/dist/lib/apple/AppleToolchain.rgr +4 -4
- package/dist/lib/apple/README.md +5 -4
- package/dist/lib/apple/apple_test.rgr +1 -1
- package/dist/lib/core/README.md +1 -1
- package/dist/lib/evg/EVG.rgr +12 -0
- package/dist/lib/evg/EVGA11yFromTree.rgr +302 -0
- package/dist/lib/evg/EVGA11yTree.rgr +894 -0
- package/dist/lib/evg/EVGBox.rgr +267 -0
- package/dist/lib/evg/EVGBoxShorthandTest.rgr +220 -0
- package/dist/lib/evg/EVGCodepoint.rgr +316 -0
- package/dist/lib/evg/EVGColor.rgr +700 -0
- package/dist/lib/evg/EVGCommands.rgr +177 -0
- package/dist/lib/evg/EVGComponent.rgr +331 -0
- package/dist/lib/evg/EVGComponentTest.rgr +387 -0
- package/dist/lib/evg/EVGConnector.rgr +541 -0
- package/dist/lib/evg/EVGConnectorTest.rgr +306 -0
- package/dist/lib/evg/EVGDisplayList.rgr +4186 -0
- package/dist/lib/evg/EVGEasing.rgr +370 -0
- package/dist/lib/evg/EVGEffectTest.rgr +253 -0
- package/dist/lib/evg/EVGElement.rgr +4914 -0
- package/dist/lib/evg/EVGFixedTest.rgr +289 -0
- package/dist/lib/evg/EVGFlexRulesTest.rgr +317 -0
- package/dist/lib/evg/EVGFlexWrapTest.rgr +246 -0
- package/dist/lib/evg/EVGFling.rgr +244 -0
- package/dist/lib/evg/EVGFocus.rgr +400 -0
- package/dist/lib/evg/EVGFocusTest.rgr +399 -0
- package/dist/lib/evg/EVGGradient.rgr +322 -0
- package/dist/lib/evg/EVGGrapheme.rgr +190 -0
- package/dist/lib/evg/EVGGrid.rgr +975 -0
- package/dist/lib/evg/EVGHitTest.rgr +208 -0
- package/dist/lib/evg/EVGHoles.rgr +294 -0
- package/dist/lib/evg/EVGHostMeasurerTest.rgr +281 -0
- package/dist/lib/evg/EVGHostTextMeasurer.rgr +331 -0
- package/dist/lib/evg/EVGHostTree.rgr +834 -0
- package/dist/lib/evg/EVGHostTreeTest.rgr +447 -0
- package/dist/lib/evg/EVGImageDecode.rgr +117 -0
- package/dist/lib/evg/EVGImageMeasurer.rgr +86 -0
- package/dist/lib/evg/EVGInspect.rgr +883 -0
- package/dist/lib/evg/EVGInvalidateTest.rgr +432 -0
- package/dist/lib/evg/EVGJsonTest.rgr +535 -0
- package/dist/lib/evg/EVGLayout.rgr +4220 -0
- package/dist/lib/evg/EVGMeasure.rgr +1267 -0
- package/dist/lib/evg/EVGOverlayTest.rgr +626 -0
- package/dist/lib/evg/EVGPatch.rgr +1721 -0
- package/dist/lib/evg/EVGPatchTest.rgr +692 -0
- package/dist/lib/evg/EVGPopoverTest.rgr +395 -0
- package/dist/lib/evg/EVGReconcile.rgr +226 -0
- package/dist/lib/evg/EVGReconcileTest.rgr +421 -0
- package/dist/lib/evg/EVGReject.rgr +126 -0
- package/dist/lib/evg/EVGRelayoutTest.rgr +375 -0
- package/dist/lib/evg/EVGRtlLayoutTest.rgr +319 -0
- package/dist/lib/evg/EVGRuler.rgr +232 -0
- package/dist/lib/evg/EVGRulerTest.rgr +172 -0
- package/dist/lib/evg/EVGSelectChrome.rgr +178 -0
- package/dist/lib/evg/EVGStyleCacheTest.rgr +419 -0
- package/dist/lib/evg/EVGStyleSheet.rgr +2148 -0
- package/dist/lib/evg/EVGStyleStateTest.rgr +407 -0
- package/dist/lib/evg/EVGStyleVarTest.rgr +471 -0
- package/dist/lib/evg/EVGText.rgr +105 -0
- package/dist/lib/evg/EVGTextEngine.rgr +536 -0
- package/dist/lib/evg/EVGTextMeasurer.rgr +720 -0
- package/dist/lib/evg/EVGTimingTest.rgr +1417 -0
- package/dist/lib/evg/EVGToolbar.rgr +1369 -0
- package/dist/lib/evg/EVGTransition.rgr +728 -0
- package/dist/lib/evg/EVGTreeJson.rgr +721 -0
- package/dist/lib/evg/EVGUnit.rgr +554 -0
- package/dist/lib/evg/EVGViewportUnitTest.rgr +236 -0
- package/dist/lib/evg/EvgApp.rgr +189 -0
- package/dist/lib/evg/EvgBitmapTracer.rgr +4277 -0
- package/dist/lib/evg/EvgBitmapTracerTest.rgr +2119 -0
- package/dist/lib/evg/EvgHost.rgr +451 -0
- package/dist/lib/evg/EvgTest.rgr +91 -0
- package/dist/lib/evg/EvgTraceColor.rgr +236 -0
- package/dist/lib/evg/EvgTraceCurve.rgr +648 -0
- package/dist/lib/evg/EvgTraceFit.rgr +767 -0
- package/dist/lib/evg/EvgTracePath.rgr +435 -0
- package/dist/lib/evg/EvgTraceTypes.rgr +559 -0
- package/dist/lib/evg/EvgViewport.rgr +313 -0
- package/dist/lib/evg/FxDemoDoc.rgr +185 -0
- package/dist/lib/evg/HOSTS.md +227 -0
- package/dist/lib/evg/ISSUES.md +835 -0
- package/dist/lib/evg/PLAN_ACCESSIBILITY.md +650 -0
- package/dist/lib/evg/PLAN_CSS_LAYOUT_AND_FONTS.md +1124 -0
- package/dist/lib/evg/PLAN_EFFECTS.md +431 -0
- package/dist/lib/evg/PLAN_EVG.md +518 -0
- package/dist/lib/evg/PLAN_EVG_RENDERER.md +1674 -0
- package/dist/lib/evg/PLAN_INSPECTOR.md +788 -0
- package/dist/lib/evg/PLAN_LINKS_AND_FORMS.md +157 -0
- package/dist/lib/evg/PLAN_NATIVE_HOSTS.md +671 -0
- package/dist/lib/evg/PLAN_VECTOR_IR.md +664 -0
- package/dist/lib/evg/PLAN_VIEW_TRANSFORM.md +322 -0
- package/dist/lib/evg/PathBuilder.rgr +333 -0
- package/dist/lib/evg/README.md +1236 -0
- package/dist/lib/evg/SPEC.md +1252 -0
- package/dist/lib/evg/SVGPathParser.rgr +1199 -0
- package/dist/lib/evg/SvgParser.rgr +1736 -0
- package/dist/lib/evg/TODO_EVG_RENDERER.md +595 -0
- package/dist/lib/evg/VectorShapes.rgr +331 -0
- package/dist/lib/evg/VectorStroke.rgr +107 -0
- package/dist/lib/evg/VectorViewBox.rgr +380 -0
- package/dist/lib/evg/agent/README.md +290 -0
- package/dist/lib/evg/agent/evg_agent.rgr +899 -0
- package/dist/lib/evg/agent/fixtures/broken.evg.json +7 -0
- package/dist/lib/evg/agent/fixtures/card.evg.json +9 -0
- package/dist/lib/evg/agent/fixtures/connector.css +63 -0
- package/dist/lib/evg/agent/fixtures/connector.evg.json +14 -0
- package/dist/lib/evg/agent/fixtures/drawn.evg.json +129 -0
- package/dist/lib/evg/agent/fixtures/gradient.evg.json +4 -0
- package/dist/lib/evg/agent/fixtures/popover.css +99 -0
- package/dist/lib/evg/agent/fixtures/popover.evg.json +30 -0
- package/dist/lib/evg/agent/roundtrip.sh +74 -0
- package/dist/lib/evg/agent/smoke.sh +230 -0
- package/dist/lib/evg/android/README.md +97 -0
- package/dist/lib/evg/android/androidstubs/AndroidStubs.kt +175 -0
- package/dist/lib/evg/android/androidstubs/Annotation.kt +10 -0
- package/dist/lib/evg/android/androidstubs/App.kt +30 -0
- package/dist/lib/evg/android/androidstubs/Content.kt +41 -0
- package/dist/lib/evg/android/androidstubs/ContentRes.kt +12 -0
- package/dist/lib/evg/android/androidstubs/InputMethod.kt +46 -0
- package/dist/lib/evg/android/androidstubs/Net.kt +6 -0
- package/dist/lib/evg/android/androidstubs/Os.kt +30 -0
- package/dist/lib/evg/android/androidstubs/Util.kt +15 -0
- package/dist/lib/evg/android/androidstubs/View.kt +113 -0
- package/dist/lib/evg/android/androidstubs/Widget.kt +16 -0
- package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidEvgSurface.kt +323 -0
- package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidTextMeasurer.kt +56 -0
- package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/RippleEffect.kt +262 -0
- package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtEvgSurface.kt +238 -0
- package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtTextMeasurer.kt +85 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgEngineThread.kt +115 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgPainter.kt +231 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgSurface.kt +117 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/RecordingSurface.kt +94 -0
- package/dist/lib/evg/apple/README.md +128 -0
- package/dist/lib/evg/apple/Sources/CoreGraphicsEvgSurface.swift +329 -0
- package/dist/lib/evg/apple/Sources/CoreTextMeasurer.swift +70 -0
- package/dist/lib/evg/apple/Sources/EvgEngineQueue.swift +105 -0
- package/dist/lib/evg/apple/Sources/EvgPainter.swift +225 -0
- package/dist/lib/evg/apple/Sources/EvgSurface.swift +163 -0
- package/dist/lib/evg/apple/Sources/RecordingSurface.swift +110 -0
- package/dist/lib/evg/bench/EvgLayoutBench.rgr +34 -0
- package/dist/lib/evg/bench/README.md +64 -0
- package/dist/lib/evg/bench/layout-bench.mjs +316 -0
- package/dist/lib/evg/bench/layout-cases.mjs +510 -0
- package/dist/lib/evg/bench/layout-conformance.mjs +254 -0
- package/dist/lib/evg/bin/.gitignore +17 -0
- package/dist/lib/evg/evg_test.rgr +313 -0
- package/dist/lib/evg/gl/README.md +198 -0
- package/dist/lib/evg/gl/a11y-paint-check.mjs +73 -0
- package/dist/lib/evg/gl/blur-check.mjs +399 -0
- package/dist/lib/evg/gl/boxmodel.json +1 -0
- package/dist/lib/evg/gl/demo.html +46 -0
- package/dist/lib/evg/gl/effect-presets.css +285 -0
- package/dist/lib/evg/gl/effect-presets.js +63 -0
- package/dist/lib/evg/gl/effect-shots.mjs +135 -0
- package/dist/lib/evg/gl/evg-a11y.js +566 -0
- package/dist/lib/evg/gl/evg-binary.js +160 -0
- package/dist/lib/evg/gl/evg-engine.js +296 -0
- package/dist/lib/evg/gl/evg-fx.js +237 -0
- package/dist/lib/evg/gl/evg-gestures.js +209 -0
- package/dist/lib/evg/gl/evg-list.js +167 -0
- package/dist/lib/evg/gl/evg-measure.js +186 -0
- package/dist/lib/evg/gl/evg-textinput.js +303 -0
- package/dist/lib/evg/gl/evg-view.js +144 -0
- package/dist/lib/evg/gl/evg-webgl.js +3942 -0
- package/dist/lib/evg/gl/fx-check.mjs +998 -0
- package/dist/lib/evg/gl/fx-demo.html +166 -0
- package/dist/lib/evg/gl/fx-demo.js +2 -0
- package/dist/lib/evg/gl/fx-serve.mjs +47 -0
- package/dist/lib/evg/gl/gestures-check.mjs +189 -0
- package/dist/lib/evg/gl/list-binary-check.mjs +152 -0
- package/dist/lib/evg/gl/measure-check.mjs +135 -0
- package/dist/lib/evg/gl/rotation-check.mjs +207 -0
- package/dist/lib/evg/gl/shift-check.mjs +113 -0
- package/dist/lib/evg/gl/stroke-check.mjs +168 -0
- package/dist/lib/evg/gl/text-snap-check.mjs +139 -0
- package/dist/lib/evg/gl/view-check.mjs +343 -0
- package/dist/lib/evg/gl/view-policy-check.mjs +184 -0
- package/dist/lib/evg/html/evg-dom.js +318 -0
- package/dist/lib/evg/html/evg-html.js +600 -0
- package/dist/lib/evg/inspect/README.md +415 -0
- package/dist/lib/evg/inspect/browser-smoke.mjs +115 -0
- package/dist/lib/evg/inspect/evg-inspect.js +947 -0
- package/dist/lib/evg/inspect/shots/css.png +0 -0
- package/dist/lib/evg/inspect/shots/dashboard.png +0 -0
- package/dist/lib/evg/inspect/shots/pptx-slide.png +0 -0
- package/dist/lib/evg/inspect/shots/state.png +0 -0
- package/dist/lib/evg/inspect/shots.mjs +226 -0
- package/dist/lib/evg/oracle/css-blur.json +576 -0
- package/dist/lib/evg/oracle/css-box.json +157 -0
- package/dist/lib/evg/oracle/css-timing.json +709 -0
- package/dist/lib/evg/oracle/css_blur_oracle.mjs +529 -0
- package/dist/lib/evg/oracle/css_box_oracle.mjs +106 -0
- package/dist/lib/evg/oracle/css_timing_oracle.mjs +389 -0
- package/dist/lib/evg/original/EVGColor.clj +310 -0
- package/dist/lib/evg/original/EVGColorContext.rgr +178 -0
- package/dist/lib/evg/original/SVGPath.rgr +627 -0
- package/dist/lib/evg/original/Vec2.crgr +103 -0
- package/dist/lib/evg/ranger.json +9 -0
- package/dist/lib/evg/showcase/README.md +246 -0
- package/dist/lib/evg/showcase/assets/emblem.svg +30 -0
- package/dist/lib/evg/showcase/assets/rosette.svg +22 -0
- package/dist/lib/evg/showcase/build.mjs +651 -0
- package/dist/lib/evg/showcase/pages/album.tsx +30 -0
- package/dist/lib/evg/showcase/pages/boxmodel.tsx +37 -0
- package/dist/lib/evg/showcase/pages/cards.tsx +41 -0
- package/dist/lib/evg/showcase/pages/chart_api.tsx +170 -0
- package/dist/lib/evg/showcase/pages/charts.tsx +219 -0
- package/dist/lib/evg/showcase/pages/drawing.tsx +160 -0
- package/dist/lib/evg/showcase/pages/emoji.tsx +91 -0
- package/dist/lib/evg/showcase/pages/flex.tsx +46 -0
- package/dist/lib/evg/showcase/pages/more.tsx +332 -0
- package/dist/lib/evg/showcase/pages/plots.tsx +262 -0
- package/dist/lib/evg/showcase/pages/svg.tsx +63 -0
- package/dist/lib/evg/showcase/pages/tables.tsx +209 -0
- package/dist/lib/evg/showcase/pages/typography.tsx +43 -0
- package/dist/lib/evg/showcase/pages/units.tsx +35 -0
- package/dist/lib/evg/showcase/pages/variants.tsx +233 -0
- package/dist/lib/evg/showcase/pages/vector.tsx +75 -0
- package/dist/lib/evg/showcase/pages/views.tsx +223 -0
- package/dist/lib/evg/showcase/tests/chart_api_smoke.mjs +339 -0
- package/dist/lib/evg/showcase/tests/gl_smoke.mjs +125 -0
- package/dist/lib/evg/showcase/themes/chart_api-default.css +15 -0
- package/dist/lib/evg/showcase/themes/charts-default.css +29 -0
- package/dist/lib/evg/showcase/themes/drawing-default.css +35 -0
- package/dist/lib/evg/showcase/themes/more-default.css +128 -0
- package/dist/lib/evg/showcase/themes/plots-default.css +18 -0
- package/dist/lib/evg/showcase/themes/showcase.css +508 -0
- package/dist/lib/evg/showcase/themes/tables-default.css +123 -0
- package/dist/lib/evg/showcase/themes/variants-default.css +15 -0
- package/dist/lib/evg/showcase/themes/views-default.css +15 -0
- package/dist/lib/evg/tools/bench_vs_potrace.mjs +290 -0
- package/dist/lib/evg/tools/evg_image_tool.rgr +488 -0
- package/dist/lib/evg/tools/evg_trace_bench.rgr +114 -0
- package/dist/lib/evg/tools/evg_trace_cli.rgr +662 -0
- package/dist/lib/evg/tools/evg_trace_cpp_bench.rgr +83 -0
- package/dist/lib/evg/tools/run_trace_bench.sh +74 -0
- package/dist/lib/evg/tools/run_trace_cli_smoke.sh +128 -0
- package/dist/lib/evg/web/responsive/EvgResponsiveCheck.rgr +271 -0
- package/dist/lib/evg/web/responsive/EvgResponsiveDemo.rgr +531 -0
- package/dist/lib/evg/web/responsive/README.md +97 -0
- package/dist/lib/evg/web/responsive/build.mjs +90 -0
- package/dist/lib/evg/web/responsive/dom-check.mjs +169 -0
- package/dist/lib/evg/web/responsive/index.html +177 -0
- package/dist/lib/evg/web/responsive/smoke.mjs +221 -0
- package/dist/lib/evg/web/tools/assets-client.mjs +95 -0
- package/dist/lib/evg/web/tools/boot-bench.mjs +189 -0
- package/dist/lib/evg/web/tools/inline-assets.mjs +119 -0
- package/dist/lib/evg/web/tools/minify.mjs +60 -0
- package/dist/lib/evg/web/tracer/build.mjs +87 -0
- package/dist/lib/evg/web/tracer/index.html +2805 -0
- package/dist/lib/evg/web/tracer/sample.png +0 -0
- package/dist/lib/evg/web/tracer/smoke.mjs +1162 -0
- package/dist/lib/evgr/Cargo.lock +21 -0
- package/dist/lib/evgr/Cargo.toml +19 -0
- package/dist/lib/evgr/README.md +140 -0
- package/dist/lib/evgr/bench/NativeBench.rgr +246 -0
- package/dist/lib/evgr/bench/compare.mjs +252 -0
- package/dist/lib/evgr/bench/speed.mjs +277 -0
- package/dist/lib/evgr/bin/.gitignore +3 -0
- package/dist/lib/evgr/src/bin/bench.rs +106 -0
- package/dist/lib/evgr/src/bin/smoke.rs +13 -0
- package/dist/lib/evgr/src/grid.rs +730 -0
- package/dist/lib/evgr/src/lib.rs +1003 -0
- package/dist/lib/evgr/src/style.rs +468 -0
- package/dist/lib/evgr/src/text.rs +83 -0
- package/dist/lib/image/BitReader.rgr +171 -0
- package/dist/lib/image/Buffer.rgr +173 -0
- package/dist/lib/image/DCT.rgr +283 -0
- package/dist/lib/image/Deflate.rgr +339 -0
- package/dist/lib/image/HuffmanDecoder.rgr +181 -0
- package/dist/lib/image/ImageBuffer.rgr +706 -0
- package/dist/lib/image/JPEGDecoder.rgr +808 -0
- package/dist/lib/image/PNGDecoder.rgr +544 -0
- package/dist/lib/image/PNGEncoder.rgr +388 -0
- package/dist/lib/image/PPMImage.rgr +224 -0
- package/dist/lib/image/ProgressiveJPEGDecoder.rgr +1154 -0
- package/dist/lib/image/README.md +33 -0
- package/dist/lib/image/RasterBuffer.rgr +294 -0
- package/dist/lib/image/VP8BoolDecoder.rgr +163 -0
- package/dist/lib/image/WebPDecoder.rgr +433 -0
- package/dist/lib/image/WebPLossless.rgr +1035 -0
- package/dist/lib/image/WebPLossy.rgr +1929 -0
- package/dist/lib/image/ranger.json +9 -0
- package/dist/lib/image/testdata/webp/anim_2f_24x16.webp +0 -0
- package/dist/lib/image/testdata/webp/fixtures.txt +33 -0
- package/dist/lib/image/testdata/webp/gen_fixtures.py +261 -0
- package/dist/lib/image/testdata/webp/ll_1x1.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_alpha_29x21.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_gradient_64x64.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_meta_32x32.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_noise_17x9.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal11_23x11.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal2_19x7.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal40_16x16.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal4_13x5.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_photo_40x30.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_predictors_64x32.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_1x1.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f0_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f1_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f2_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f3_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f0_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f1_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f2_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f3_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alpha_33x17.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_exif_15x11.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_i16_96x80.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_nofilter_24x20.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_odd_17x9.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_photo_48x40.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_q100_20x18.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_sharp_40x36.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_simple_filter_33x31.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_vpx_parts8_37x45.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_vpx_skip_96x80.webp +0 -0
- package/dist/lib/image/tests/WebPDecodeTool.rgr +81 -0
- package/dist/lib/image/tests/WebPDecoderTest.rgr +1162 -0
- package/dist/lib/image/tests/run_webp_tests.sh +39 -0
- package/dist/lib/rust/RsJson.rgr +468 -0
- package/dist/lib/rust/RsPrelude.rgr +1663 -0
- package/dist/lib/shell_test.rgr +7 -7
- package/dist/lib/stdlib.rgr +21 -5
- package/dist/lib/zip/ranger.json +6 -0
- package/dist/rgrc.js +87318 -67610
- package/package.json +1010 -1040
- package/dist/README.md +0 -117
- package/dist/package.json +0 -47
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; ==============================================================================
|
|
4
|
+
; EvgTraceTypes.rgr — shared types for bitmap tracing
|
|
5
|
+
; ==============================================================================
|
|
6
|
+
|
|
7
|
+
class EvgTracePoint {
|
|
8
|
+
def x:double 0.0
|
|
9
|
+
def y:double 0.0
|
|
10
|
+
|
|
11
|
+
Constructor () {
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
sfn of:EvgTracePoint (x:double y:double) {
|
|
15
|
+
def p (new EvgTracePoint())
|
|
16
|
+
p.x = x
|
|
17
|
+
p.y = y
|
|
18
|
+
return p
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
sfn ofInt:EvgTracePoint (x:int y:int) {
|
|
22
|
+
def p (new EvgTracePoint())
|
|
23
|
+
p.x = (to_double x)
|
|
24
|
+
p.y = (to_double y)
|
|
25
|
+
return p
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
; One closed edge walk before curve fitting.
|
|
30
|
+
class EvgTraceRing {
|
|
31
|
+
def pts:[EvgTracePoint]
|
|
32
|
+
def area:int 0
|
|
33
|
+
; "+" = black exterior walk, "-" = white (hole) walk — mirrors Potrace.
|
|
34
|
+
def sign:string "+"
|
|
35
|
+
def minX:int 0
|
|
36
|
+
def minY:int 0
|
|
37
|
+
def maxX:int 0
|
|
38
|
+
def maxY:int 0
|
|
39
|
+
|
|
40
|
+
Constructor () {
|
|
41
|
+
def p:[EvgTracePoint]
|
|
42
|
+
pts = p
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fn len:int () {
|
|
46
|
+
return (array_length pts)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
; One colored path layer after posterize / multi-color trace.
|
|
51
|
+
class EvgTraceLayer {
|
|
52
|
+
def fillHex:string "#000000"
|
|
53
|
+
def pathData:string ""
|
|
54
|
+
def ringCount:int 0
|
|
55
|
+
def commandCount:int 0
|
|
56
|
+
; How the layer is filled: "flat" uses fillHex alone; "linear" and "radial"
|
|
57
|
+
; add a gradient, chosen per region by which one describes it best. Only
|
|
58
|
+
; toSVG renders these — an EVGElement carries a single color, so
|
|
59
|
+
; toEVGElements falls back to fillHex.
|
|
60
|
+
def fillKind:string "flat"
|
|
61
|
+
; Linear: (x0,y0) → (x1,y1). Only linear gradients are emitted; a radial
|
|
62
|
+
; one infers shapes the picture does not have unless the region is round.
|
|
63
|
+
def gx0:double 0.0
|
|
64
|
+
def gy0:double 0.0
|
|
65
|
+
def gx1:double 0.0
|
|
66
|
+
def gy1:double 0.0
|
|
67
|
+
; Color at the start of the gradient and at its end.
|
|
68
|
+
def stopA:string "#000000"
|
|
69
|
+
def stopB:string "#000000"
|
|
70
|
+
|
|
71
|
+
Constructor () {
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
class EvgTraceOptions {
|
|
76
|
+
; Speckle filter: drop rings whose |area| is at most this (Potrace default 2).
|
|
77
|
+
def turdsize:int 2
|
|
78
|
+
; Corner threshold. Higher → smoother (fewer corners). Potrace default 1.0.
|
|
79
|
+
def alphamax:double 1.0
|
|
80
|
+
; "minority" | "majority" | "black" | "white" | "left" | "right"
|
|
81
|
+
def turnpolicy:string "minority"
|
|
82
|
+
; When true, fit cubics; when false, emit a polygon.
|
|
83
|
+
def optcurve:boolean true
|
|
84
|
+
; Curve optimization tolerance (Potrace -O; used by optiCurve).
|
|
85
|
+
def opttolerance:double 0.2
|
|
86
|
+
; Luminance threshold 0..255. Negative → Otsu on the source image.
|
|
87
|
+
def threshold:int 128
|
|
88
|
+
; Trace dark pixels as foreground (Potrace blackOnWhite).
|
|
89
|
+
def blackOnWhite:boolean true
|
|
90
|
+
; Mono fill for binary traces (SVG / EVG). Default black.
|
|
91
|
+
def fillHex:string "#000000"
|
|
92
|
+
; 1 = mono (threshold). >1 = quantize ImageBuffer into this many colors
|
|
93
|
+
; and trace each palette entry as its own evenodd path layer.
|
|
94
|
+
def colorCount:int 1
|
|
95
|
+
; When posterizing, skip near-white / background swatches (luma >= this).
|
|
96
|
+
; 250 keeps paper-white out of typical scans; set 256 to keep white.
|
|
97
|
+
def skipLuma:int 250
|
|
98
|
+
; Posterize: a pixel counts as a region interior when every 4-neighbour is
|
|
99
|
+
; within this per-channel distance. Anti-aliased boundary pixels fail the
|
|
100
|
+
; test and are kept out of the palette vote.
|
|
101
|
+
def flatTolerance:int 12
|
|
102
|
+
; Let a boundary pixel join a region that actually touches it instead of a
|
|
103
|
+
; swatch it only resembles — see assignLabels.
|
|
104
|
+
def edgeSnap:boolean true
|
|
105
|
+
; How much worse a touching region may fit before the snap is refused.
|
|
106
|
+
; 1.0 = only when it fits at least as well; larger = snap more eagerly.
|
|
107
|
+
def snapRatio:double 1.5
|
|
108
|
+
; Extra weight on the luma term of the palette distance (1 = plain RGB).
|
|
109
|
+
; Only consulted by colorSpace "rgb".
|
|
110
|
+
def lumaWeight:int 3
|
|
111
|
+
; Which space the posterizer measures color difference in:
|
|
112
|
+
; "rgb" — weighted RGB with an extra luma term (lumaWeight)
|
|
113
|
+
; "oklab" — Euclidean distance in OKLab, where that distance actually
|
|
114
|
+
; tracks perceived difference. Scaled onto the same numeric
|
|
115
|
+
; range as "rgb" (black against white is 390150 in both), so
|
|
116
|
+
; minColorDelta, snapRatio and the rest keep their meaning.
|
|
117
|
+
; Costs two cube roots per comparison; buys a palette that is spent on
|
|
118
|
+
; colors a viewer can tell apart rather than on whatever RGB happened to
|
|
119
|
+
; stretch.
|
|
120
|
+
def colorSpace:string "rgb"
|
|
121
|
+
; How the palette is decided:
|
|
122
|
+
; "auto" — quantize the image; paletteHex is ignored
|
|
123
|
+
; "fixed" — use paletteHex exactly, in the given order; colorCount is
|
|
124
|
+
; ignored, and every pixel goes to whichever of them is nearest
|
|
125
|
+
; "seeded" — paletteHex are pinned and the quantizer fills the rest up to
|
|
126
|
+
; colorCount around them
|
|
127
|
+
; An unparseable or empty paletteHex falls back to "auto".
|
|
128
|
+
def paletteMode:string "auto"
|
|
129
|
+
; Colors for "fixed" / "seeded" — anything EVGColor.parse accepts:
|
|
130
|
+
; "#1a1a1a", "#f80", "rgb(20 30 40)", "crimson".
|
|
131
|
+
def paletteHex:[string]
|
|
132
|
+
; What a swatch is spent on when the quantizer picks one:
|
|
133
|
+
; "area" — the biggest regions win (the default, and what a photo's
|
|
134
|
+
; large flat background will always take)
|
|
135
|
+
; "balanced" — sqrt of area, so a small vivid object can still claim one
|
|
136
|
+
; "distinct" — every color present counts once, however much of it there
|
|
137
|
+
; is; the palette covers the picture's gamut rather than its
|
|
138
|
+
; mass, above a noise floor
|
|
139
|
+
; This governs the seeding AND the Lloyd passes that follow it. Steering
|
|
140
|
+
; only the seeds is the same as not steering at all — the passes are the
|
|
141
|
+
; step that decides where a swatch settles, and run on population they walk
|
|
142
|
+
; every seed back onto the mass it was chosen to get away from.
|
|
143
|
+
def paletteBias:string "area"
|
|
144
|
+
; How much being colorful counts on top of paletteBias, in percent: at 100
|
|
145
|
+
; a fully colored swatch is worth twice its area, at 300 four times.
|
|
146
|
+
;
|
|
147
|
+
; A picture's subject is very often a small saturated thing on a large
|
|
148
|
+
; unsaturated ground — the ochre hulls of two boats against grey sea and
|
|
149
|
+
; beige paper. Weighted by area those pixels never earn a swatch, and the
|
|
150
|
+
; result is not that the color comes out approximate: it comes out *gone*,
|
|
151
|
+
; because nothing else in the palette is anywhere near it. Measured on the
|
|
152
|
+
; Hokusai wave at eight colors, the nearest palette entry to the hulls sits
|
|
153
|
+
; 48 units away and is a grey; the color a viewer would name in the picture
|
|
154
|
+
; is not in the output at all.
|
|
155
|
+
;
|
|
156
|
+
; 0 = area and colorfulness are unrelated, which is the old behaviour.
|
|
157
|
+
def paletteChroma:int 0
|
|
158
|
+
; --- The palette objective ---------------------------------------------
|
|
159
|
+
;
|
|
160
|
+
; Applied to the finished palette after the picture's regions have been
|
|
161
|
+
; decided, so these move what it is painted with and not where its edges
|
|
162
|
+
; are. All four are identity at their defaults. Measured in OKLab.
|
|
163
|
+
;
|
|
164
|
+
; Chroma scale, percent. Below 100 breaks every color toward grey, which is
|
|
165
|
+
; what a painter means by a broken tone; above 100 enriches. 100 = the
|
|
166
|
+
; colors the picture actually holds.
|
|
167
|
+
def paletteMute:int 100
|
|
168
|
+
; Chroma floor, in thousandths of an OKLab unit. No swatch comes out below
|
|
169
|
+
; it, so the palette can be broken toward grey without any of it arriving
|
|
170
|
+
; as dead grey — a neutral is tinted in the palette's own average hue
|
|
171
|
+
; instead. 20 is a tint you notice without being able to name; 60 is an
|
|
172
|
+
; openly colored neutral. 0 = no floor.
|
|
173
|
+
def paletteTint:int 0
|
|
174
|
+
; Warmth, in thousandths of an OKLab unit along the yellow–blue axis.
|
|
175
|
+
; Positive is warmer. A shift rather than a hue rotation, because that is
|
|
176
|
+
; what a temperature change is: it moves a neutral toward yellow instead of
|
|
177
|
+
; spinning it to some unrelated hue.
|
|
178
|
+
def paletteWarm:int 0
|
|
179
|
+
; Lightness spread about the palette's own mean, percent. Below 100 closes
|
|
180
|
+
; the palette up toward a mid tone, above 100 opens it out. Does not touch
|
|
181
|
+
; the picture's own contrast, only how far apart the swatches sit.
|
|
182
|
+
def paletteContrast:int 100
|
|
183
|
+
; Swatches closer than this (largest per-channel difference) are merged
|
|
184
|
+
; after quantization. Asking for more colors than the image actually holds
|
|
185
|
+
; otherwise splits one region between two near-identical swatches, and each
|
|
186
|
+
; half then falls under turdsize — which is how outlines turn into dashes.
|
|
187
|
+
def minColorDelta:int 10
|
|
188
|
+
; Banding suppression. A quantizer cuts a hard edge wherever a smooth ramp
|
|
189
|
+
; crosses the midpoint between two swatches, which is a contour the picture
|
|
190
|
+
; does not have; meanwhile a real edge between two *similar* colors can go
|
|
191
|
+
; unmarked. Read small differences as continuous and large ones as a break:
|
|
192
|
+
; "off" — every pixel takes its own nearest swatch (the default)
|
|
193
|
+
; "smooth" — grow regions across neighbours that differ by at most
|
|
194
|
+
; contourEdge, then give the whole region the one swatch
|
|
195
|
+
; nearest its mean. A ramp becomes one region and loses its
|
|
196
|
+
; false contour; a step larger than contourEdge still splits.
|
|
197
|
+
; "overlay" — the same growth, but the shapes are stacked instead of
|
|
198
|
+
; partitioned. A surface is finished to its end; every edge it
|
|
199
|
+
; ran into becomes a seed for a shape started on the far side
|
|
200
|
+
; and drawn ON TOP of it. An overlay may cover ground the
|
|
201
|
+
; surface below already claimed, so a boundary that fades for
|
|
202
|
+
; a few pixels — which lets the flood leak and swallow the
|
|
203
|
+
; shape behind it — is no longer a lost shape: it is repainted
|
|
204
|
+
; from above. It stops at an edge, and it also stops where it
|
|
205
|
+
; has become indistinguishable from what is under it, so an
|
|
206
|
+
; overlay only exists where it shows.
|
|
207
|
+
; Off by default because it is a real segmentation, and segmentation has
|
|
208
|
+
; failure modes: where two areas are joined by a gradual path it will merge
|
|
209
|
+
; them, and that mistake is a large one.
|
|
210
|
+
def contourMode:string "off"
|
|
211
|
+
; "overlay": how close to the color already painted underneath is close
|
|
212
|
+
; enough to stop. An overlay that matches its background adds nothing.
|
|
213
|
+
def overlaySimilar:int 8
|
|
214
|
+
; "overlay": keep every shape inside one region of the picture the
|
|
215
|
+
; quantizer already produced. An overlay shape is meant to be a refinement
|
|
216
|
+
; of that picture — one region resolved into several shapes stacked in z —
|
|
217
|
+
; not a second opinion about where the regions are. Allowed to disagree, it
|
|
218
|
+
; grows a surface from a face out into the background behind it and paints
|
|
219
|
+
; the pair one color, which is how a portrait came back as mush. This also
|
|
220
|
+
; bounds what any single shape can claim, since no shape outgrows its
|
|
221
|
+
; region.
|
|
222
|
+
def overlayFollowBase:boolean true
|
|
223
|
+
; Where the picture needs fine work, let overlay do fine work.
|
|
224
|
+
;
|
|
225
|
+
; An eye is a few pixels holding four plainly different colors — white,
|
|
226
|
+
; iris, lash, skin — and a pass coarse enough to be sensible on a cheek
|
|
227
|
+
; throws all of it away. A window counts as detail when it holds at least
|
|
228
|
+
; detailSwatches distinct swatches *and* spans at least detailSpread levels
|
|
229
|
+
; of luma: both halves are needed, or a gradient (few swatches, wide spread)
|
|
230
|
+
; and noise inside one flat color (one swatch) both read as detail.
|
|
231
|
+
; Inside such a window overlay divides its smallest-area and its similarity
|
|
232
|
+
; limits by detailBoost, so small strong shapes are drawn there and nowhere
|
|
233
|
+
; else. detailSwatches below 2, or detailBoost below 2, turns it off.
|
|
234
|
+
; Swept against landmarks on a portrait: at 4 swatches / 120 luma / radius
|
|
235
|
+
; 2 the mask covers 2.8% of the frame and fires on both eyes while missing
|
|
236
|
+
; the cheek, the suit, the curtain and the flag. Three swatches lets the
|
|
237
|
+
; flag in; five loses one of the eyes.
|
|
238
|
+
def detailSwatches:int 4
|
|
239
|
+
def detailSpread:int 120
|
|
240
|
+
def detailRadius:int 2
|
|
241
|
+
def detailBoost:int 4
|
|
242
|
+
; In a detail neighbourhood, let an overlay keep its own measured color
|
|
243
|
+
; instead of snapping it to the palette. This is the only way the mode can
|
|
244
|
+
; add resolution rather than redraw what is already there: everywhere else
|
|
245
|
+
; an overlay is snapped to the same swatches the base picture used, and a
|
|
246
|
+
; shape sitting inside one region has a mean dominated by that region — so
|
|
247
|
+
; it snaps back to that region's own swatch and repaints it. Unsnapped, the
|
|
248
|
+
; white of an eye can be white and the pupil black even when neither is in
|
|
249
|
+
; the palette. It costs the guarantee that the color count is a hard ceiling,
|
|
250
|
+
; which is why it is a separate switch; the detail mask covers a few percent
|
|
251
|
+
; of a frame, so the cost is bounded.
|
|
252
|
+
def detailTrueColor:boolean false
|
|
253
|
+
; How many colors a detail neighbourhood gets to quantize itself into.
|
|
254
|
+
; Zoom into an eye on its own and the tracer renders it beautifully, because
|
|
255
|
+
; the whole color budget is spent on an eye. Give it the whole face and the
|
|
256
|
+
; eye gets two swatches out of ten and comes back as a smudge that keeps the
|
|
257
|
+
; outline and loses the lid, the lash line and the opening. A detail
|
|
258
|
+
; neighbourhood therefore builds its own small palette out of its own pixels
|
|
259
|
+
; — which is what "zoom in on it" means, done in place — and its shapes are
|
|
260
|
+
; drawn on top of the picture the global palette produced. 0 turns it off.
|
|
261
|
+
def detailColors:int 4
|
|
262
|
+
; Smallest ring a detail shape may keep, as a share of its neighbourhood, in
|
|
263
|
+
; percent. The local palette buys structure inside a feature and speckle
|
|
264
|
+
; along with it, and this is what separates them: each band traces to one
|
|
265
|
+
; large ring plus a spray of small ones, and the spray is the speckle.
|
|
266
|
+
; Swept on a portrait's eyes — 0%: every bit of structure and every bit of
|
|
267
|
+
; grain, 687 KB. 8%: the lid, the lash line and the opening all still read,
|
|
268
|
+
; the grain is gone, 599 KB. 15% and up: it starts eating the structure too
|
|
269
|
+
; and converges on what the plain algorithm already gives.
|
|
270
|
+
def detailMinShare:int 8
|
|
271
|
+
; Detail neighbourhoods share one palette, and this is how close two of
|
|
272
|
+
; their colors may be before they become one entry in it. Each
|
|
273
|
+
; neighbourhood still derives its own bands from its own pixels — that is
|
|
274
|
+
; the point of the feature — but derived in ignorance of each other, forty
|
|
275
|
+
; neighbourhoods invent forty nearly identical browns. Measured on a
|
|
276
|
+
; portrait: 456 distinct fills unmerged, 234 at a tolerance of 8, 91 at 16,
|
|
277
|
+
; 49 at 24. 0 disables the merge and lets every neighbourhood keep its own.
|
|
278
|
+
def detailColorMerge:int 16
|
|
279
|
+
; The most colors the detail neighbourhoods may add between them. Merging
|
|
280
|
+
; near-duplicates bounds nothing on its own: colors that are genuinely
|
|
281
|
+
; different keep accumulating, one per neighbourhood per band, and a busy
|
|
282
|
+
; picture has hundreds of neighbourhoods — a portrait asked for six swatches
|
|
283
|
+
; came back with 103. Once this many have been taken, a new band uses the
|
|
284
|
+
; nearest one already in hand instead of adding another, so the color count
|
|
285
|
+
; is at most colorCount + this, whatever the picture does. 0 removes the
|
|
286
|
+
; ceiling.
|
|
287
|
+
def detailColorMax:int 12
|
|
288
|
+
; A step only counts as a boundary when it is *unique* in its
|
|
289
|
+
; neighbourhood — the strongest one across its own direction, so a noisy
|
|
290
|
+
; pixel does not out-vote the ridge beside it — and *continuous*, part of a
|
|
291
|
+
; run at least this many pixels long. Without both, every speck in a
|
|
292
|
+
; photograph is a boundary, and the tracer spends its shapes on them.
|
|
293
|
+
; 0 turns the filter off and takes every step at face value.
|
|
294
|
+
def edgeMinRun:int 3
|
|
295
|
+
; Largest per-channel step still counted as continuous. Small on purpose:
|
|
296
|
+
; at 10 a soft-edged object merges into the field behind it.
|
|
297
|
+
def contourEdge:int 3
|
|
298
|
+
; How far a region may drift from its own running mean before it stops
|
|
299
|
+
; growing. This is the leash on the failure above: without it one ramp can
|
|
300
|
+
; walk across the whole picture.
|
|
301
|
+
def contourSpread:int 48
|
|
302
|
+
; Fill each region with the gradient that describes it rather than one flat
|
|
303
|
+
; color: fit a flat, a linear and a radial model per region and keep
|
|
304
|
+
; whichever leaves the least error. Needs the continuity segmentation, so
|
|
305
|
+
; turning this on runs it whether or not contourMode asked for it.
|
|
306
|
+
; Rendered by toSVG only.
|
|
307
|
+
def gradientFill:boolean false
|
|
308
|
+
; A gradient only replaces the flat fill when it explains this much more of
|
|
309
|
+
; the region's variation, in percent. Keeps a nearly flat region flat.
|
|
310
|
+
def gradientGain:int 15
|
|
311
|
+
; How the color layers are stacked:
|
|
312
|
+
; "stacked" — layer i covers every pixel at or above it in the palette
|
|
313
|
+
; order, so the layers are painted over one another and a
|
|
314
|
+
; curve-fitting gap exposes the neighbouring color, not the
|
|
315
|
+
; page. Two independent fits of the same pixel boundary never
|
|
316
|
+
; agree exactly, which is where the white hairlines came from.
|
|
317
|
+
; "flat" — one disjoint region per swatch; smaller, and correct only if
|
|
318
|
+
; nothing is ever going to look at the seams.
|
|
319
|
+
def layerMode:string "stacked"
|
|
320
|
+
; How the `d` attribute is written. The geometry is the same either way:
|
|
321
|
+
; "plain" — absolute M/L/C at four decimals, what VectorShapes writes
|
|
322
|
+
; for the rest of the vector stack
|
|
323
|
+
; "compact" — per segment the shorter of the absolute and relative form,
|
|
324
|
+
; H/V for axis-aligned lines, S for mirrored cubic handles,
|
|
325
|
+
; numbers trimmed to pathPrecision, and separators only where
|
|
326
|
+
; the SVG grammar needs one. Same picture, roughly half the
|
|
327
|
+
; bytes. See EvgTracePath.
|
|
328
|
+
def pathFormat:string "compact"
|
|
329
|
+
; Decimal places kept in "compact". Two is a hundredth of a pixel, well
|
|
330
|
+
; below what a trace resolves; the coordinates are rounded before the
|
|
331
|
+
; degenerate-segment cleanup, so the rounding does not leave debris behind.
|
|
332
|
+
def pathPrecision:int 2
|
|
333
|
+
; Posterize: passes of a 3×3 median over the color planes before anything
|
|
334
|
+
; else looks at them. A photograph's per-pixel noise otherwise survives
|
|
335
|
+
; quantization as speckle, and every extra color splits it further, so the
|
|
336
|
+
; trace gains fragments instead of shapes. 0 = off, which is what line art
|
|
337
|
+
; and flat-color art want: a median would eat their thin strokes.
|
|
338
|
+
def smooth:int 0
|
|
339
|
+
; Posterize: a connected run of pixels smaller than this joins the region
|
|
340
|
+
; around it instead of being traced. Without it turdsize simply deletes
|
|
341
|
+
; those rings and leaves holes, so coverage falls as colorCount rises.
|
|
342
|
+
def minRegion:int 6
|
|
343
|
+
; The other half of the minRegion test, in per-channel color units: a run
|
|
344
|
+
; below minRegion is still kept when the swatch it would be absorbed into
|
|
345
|
+
; is at least this far away. Size on its own cannot tell noise from
|
|
346
|
+
; subject — the spray off a wave, a boat on the sea and the white of an eye
|
|
347
|
+
; are each a few pixels that no larger shape puts back, while a few pixels
|
|
348
|
+
; of a neighbouring blue inside blue are exactly what minRegion is for.
|
|
349
|
+
; Measured on the Hokusai wave at colorCount 16: absorbing everything costs
|
|
350
|
+
; 15 RMSE points and both boats; keeping what stands out recovers nearly
|
|
351
|
+
; all of it at a third of the extra bytes. 0 restores the unconditional
|
|
352
|
+
; absorb.
|
|
353
|
+
def absorbContrast:int 40
|
|
354
|
+
; Background handling for posterize:
|
|
355
|
+
; "auto" — flood the page color in from the border and drop only that,
|
|
356
|
+
; so a white belly or highlight inside the subject survives.
|
|
357
|
+
; Falls back to "luma" when the border is not one flat color.
|
|
358
|
+
; "color" — the same flood, but from a color you name in bgColor rather
|
|
359
|
+
; than the one the border happens to hold, and with no
|
|
360
|
+
; uniformity test to pass. What to reach for when "auto"
|
|
361
|
+
; declines because the border is not flat enough.
|
|
362
|
+
; "luma" — the old rule: drop every pixel with luma >= skipLuma.
|
|
363
|
+
; "none" — paint everything opaque.
|
|
364
|
+
def bgMode:string "auto"
|
|
365
|
+
; The background color for bgMode "color". Anything EVGColor.parse accepts.
|
|
366
|
+
def bgColor:string "#ffffff"
|
|
367
|
+
; Per-channel tolerance for the "auto" background flood.
|
|
368
|
+
def bgTolerance:int 24
|
|
369
|
+
|
|
370
|
+
Constructor () {
|
|
371
|
+
def ph:[string]
|
|
372
|
+
paletteHex = ph
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
sfn defaults:EvgTraceOptions () {
|
|
376
|
+
return (new EvgTraceOptions())
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
; A starting point for a kind of picture. Forty-one knobs is the right
|
|
380
|
+
; number for a tracer that has to handle a scanned blueprint and a
|
|
381
|
+
; photograph with the same code, and the wrong number to hand somebody who
|
|
382
|
+
; has one image and a deadline. Each preset below is a setting that was
|
|
383
|
+
; measured rather than guessed; from there the individual knobs still work.
|
|
384
|
+
;
|
|
385
|
+
; "lineart" — one-color ink on paper. No median (it eats thin strokes),
|
|
386
|
+
; no speckle absorb, Otsu picks the threshold.
|
|
387
|
+
; "poster" — flat-color art: few colors, hard edges, keep every one.
|
|
388
|
+
; "photo" — a photograph: median away the sensor grain, absorb the
|
|
389
|
+
; speckle it leaves, and spend the palette on area.
|
|
390
|
+
; "broken" — the palette chosen for its colors rather than for its
|
|
391
|
+
; fidelity: swatches spent on covering the gamut, then
|
|
392
|
+
; enriched and tinted. What to reach for when the measured
|
|
393
|
+
; palette comes back grey.
|
|
394
|
+
; "print" — a detailed picture with hard edges and fine marks, the
|
|
395
|
+
; Hokusai wave being the case it was tuned on: absorb small
|
|
396
|
+
; runs, but not the ones that stand out from what surrounds
|
|
397
|
+
; them, which is where the spray and the boats live.
|
|
398
|
+
;
|
|
399
|
+
; An unknown name returns the plain defaults.
|
|
400
|
+
sfn preset:EvgTraceOptions (name:string) {
|
|
401
|
+
def o (new EvgTraceOptions())
|
|
402
|
+
if (name == "lineart") {
|
|
403
|
+
o.colorCount = 1
|
|
404
|
+
o.threshold = (0 - 1)
|
|
405
|
+
o.smooth = 0
|
|
406
|
+
o.minRegion = 0
|
|
407
|
+
return o
|
|
408
|
+
}
|
|
409
|
+
if (name == "poster") {
|
|
410
|
+
o.colorCount = 8
|
|
411
|
+
o.smooth = 0
|
|
412
|
+
o.minRegion = 4
|
|
413
|
+
o.absorbContrast = 24
|
|
414
|
+
o.minColorDelta = 12
|
|
415
|
+
return o
|
|
416
|
+
}
|
|
417
|
+
if (name == "photo") {
|
|
418
|
+
o.colorCount = 16
|
|
419
|
+
o.smooth = 1
|
|
420
|
+
o.minRegion = 8
|
|
421
|
+
o.absorbContrast = 56
|
|
422
|
+
o.paletteBias = "area"
|
|
423
|
+
return o
|
|
424
|
+
}
|
|
425
|
+
; The palette dialled rather than measured. Measured means come out
|
|
426
|
+
; grey because the mean of a large region is grey; a picture painted in
|
|
427
|
+
; eight of them has no color a painter would have chosen. This spends
|
|
428
|
+
; the swatches on covering the picture's gamut instead of its mass, and
|
|
429
|
+
; then enriches and tints what comes back. On the Hokusai wave it is
|
|
430
|
+
; what puts the ochre of the boat hulls into the output at all: the
|
|
431
|
+
; nearest palette entry to the hulls goes from 48 units away and grey
|
|
432
|
+
; to 27 away and ochre, and the error measured over the hulls alone
|
|
433
|
+
; falls from 30.4 to 22.4 — below what vtracer manages there.
|
|
434
|
+
if (name == "broken") {
|
|
435
|
+
o.colorCount = 8
|
|
436
|
+
o.smooth = 0
|
|
437
|
+
o.minRegion = 4
|
|
438
|
+
o.absorbContrast = 24
|
|
439
|
+
o.paletteBias = "distinct"
|
|
440
|
+
o.paletteChroma = 300
|
|
441
|
+
o.paletteMute = 130
|
|
442
|
+
o.paletteTint = 30
|
|
443
|
+
return o
|
|
444
|
+
}
|
|
445
|
+
if (name == "print") {
|
|
446
|
+
o.colorCount = 16
|
|
447
|
+
o.smooth = 0
|
|
448
|
+
o.minRegion = 6
|
|
449
|
+
o.absorbContrast = 32
|
|
450
|
+
return o
|
|
451
|
+
}
|
|
452
|
+
return o
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
; Packed 0/1 bitmap. Index = y * w + x.
|
|
457
|
+
class EvgBinaryBitmap {
|
|
458
|
+
def w:int 0
|
|
459
|
+
def h:int 0
|
|
460
|
+
def data:[int]
|
|
461
|
+
|
|
462
|
+
Constructor () {
|
|
463
|
+
def d:[int]
|
|
464
|
+
data = d
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
sfn create:EvgBinaryBitmap (w:int h:int) {
|
|
468
|
+
def bm (new EvgBinaryBitmap())
|
|
469
|
+
bm.w = w
|
|
470
|
+
bm.h = h
|
|
471
|
+
def d:[int]
|
|
472
|
+
def n:int (w * h)
|
|
473
|
+
def i:int 0
|
|
474
|
+
while (i < n) {
|
|
475
|
+
push d 0
|
|
476
|
+
i = (i + 1)
|
|
477
|
+
}
|
|
478
|
+
bm.data = d
|
|
479
|
+
return bm
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
fn size:int () {
|
|
483
|
+
return (array_length data)
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
fn at:boolean (x:int y:int) {
|
|
487
|
+
if (x < 0) {
|
|
488
|
+
return false
|
|
489
|
+
}
|
|
490
|
+
if (y < 0) {
|
|
491
|
+
return false
|
|
492
|
+
}
|
|
493
|
+
if (x >= w) {
|
|
494
|
+
return false
|
|
495
|
+
}
|
|
496
|
+
if (y >= h) {
|
|
497
|
+
return false
|
|
498
|
+
}
|
|
499
|
+
def v:int (itemAt data ((y * w) + x))
|
|
500
|
+
return (v == 1)
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
fn setBit:void (x:int y:int on:boolean) {
|
|
504
|
+
if (x < 0) {
|
|
505
|
+
return
|
|
506
|
+
}
|
|
507
|
+
if (y < 0) {
|
|
508
|
+
return
|
|
509
|
+
}
|
|
510
|
+
if (x >= w) {
|
|
511
|
+
return
|
|
512
|
+
}
|
|
513
|
+
if (y >= h) {
|
|
514
|
+
return
|
|
515
|
+
}
|
|
516
|
+
if on {
|
|
517
|
+
set data ((y * w) + x) 1
|
|
518
|
+
} {
|
|
519
|
+
set data ((y * w) + x) 0
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
fn flip:void (x:int y:int) {
|
|
524
|
+
if (this.at(x y)) {
|
|
525
|
+
this.setBit(x y false)
|
|
526
|
+
} {
|
|
527
|
+
this.setBit(x y true)
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
fn copy:EvgBinaryBitmap () {
|
|
532
|
+
def bm (new EvgBinaryBitmap())
|
|
533
|
+
bm.w = w
|
|
534
|
+
bm.h = h
|
|
535
|
+
def d:[int]
|
|
536
|
+
def n:int (array_length data)
|
|
537
|
+
def i:int 0
|
|
538
|
+
while (i < n) {
|
|
539
|
+
push d (itemAt data i)
|
|
540
|
+
i = (i + 1)
|
|
541
|
+
}
|
|
542
|
+
bm.data = d
|
|
543
|
+
return bm
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
; Find the next set pixel at or after linear index `start`.
|
|
547
|
+
fn findNext:int (start:int) {
|
|
548
|
+
def n:int (array_length data)
|
|
549
|
+
def i:int start
|
|
550
|
+
while (i < n) {
|
|
551
|
+
if ((itemAt data i) == 1) {
|
|
552
|
+
return i
|
|
553
|
+
}
|
|
554
|
+
i = (i + 1)
|
|
555
|
+
}
|
|
556
|
+
return (0 - 1)
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|