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.
- package/CHANGELOG.md +1160 -19
- package/LICENSE +3 -1
- package/README.md +124 -29
- package/dist/Lang.rgr +1188 -290
- package/dist/api.d.ts +2343 -879
- package/dist/api.js +79924 -56922
- 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,370 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; ==============================================================================
|
|
4
|
+
; EVGEasing — CSS timing functions
|
|
5
|
+
; ==============================================================================
|
|
6
|
+
;
|
|
7
|
+
; A transition needs two numbers from the clock: how far through it is, and how
|
|
8
|
+
; far along it therefore LOOKS. Those are not the same number, and the gap
|
|
9
|
+
; between them is most of why a browser's motion feels different from a
|
|
10
|
+
; hand-rolled `t += dt` one.
|
|
11
|
+
;
|
|
12
|
+
; input progress elapsed / duration. Linear, always.
|
|
13
|
+
; output progress what the timing function makes of it. This is what the
|
|
14
|
+
; value is actually interpolated by.
|
|
15
|
+
;
|
|
16
|
+
; Two families, which is all CSS has:
|
|
17
|
+
;
|
|
18
|
+
; cubic-bezier(x1 y1 x2 y2) a curve from (0,0) to (1,1) with two control
|
|
19
|
+
; points. `ease`, `ease-in`, `ease-out` and
|
|
20
|
+
; `ease-in-out` are named instances of it, and so
|
|
21
|
+
; is `linear`.
|
|
22
|
+
; steps(n start|end) n discrete jumps.
|
|
23
|
+
;
|
|
24
|
+
; The awkward part is that the curve is parametric — both x and y are functions
|
|
25
|
+
; of a parameter that is NOT the input progress — so the output cannot be read
|
|
26
|
+
; off directly. Given x, the parameter has to be solved for first. Newton–
|
|
27
|
+
; Raphson converges in a handful of iterations over almost the whole range, and
|
|
28
|
+
; where it does not (a control point outside [0,1] can flatten the derivative)
|
|
29
|
+
; bisection finishes the job. This is the method every engine uses, and matching
|
|
30
|
+
; it is the difference between 5e-6 of the browser and 1e-2 of it.
|
|
31
|
+
;
|
|
32
|
+
; The control points for the four keywords, and every number this file is
|
|
33
|
+
; checked against, are CAPTURED rather than quoted: `oracle/css-timing.json`
|
|
34
|
+
; holds samples taken off a real `Animation` at thirteen input progresses.
|
|
35
|
+
; `EVGTimingTest.rgr` is those samples.
|
|
36
|
+
; ==============================================================================
|
|
37
|
+
|
|
38
|
+
class EVGEasing {
|
|
39
|
+
|
|
40
|
+
; 0 = cubic-bezier, 1 = steps
|
|
41
|
+
def kind:int 0
|
|
42
|
+
def x1:double 0.0
|
|
43
|
+
def y1:double 0.0
|
|
44
|
+
def x2:double 1.0
|
|
45
|
+
def y2:double 1.0
|
|
46
|
+
def stepCount:int 1
|
|
47
|
+
; `steps(n, start)` jumps at the beginning of each interval, so it leaves
|
|
48
|
+
; zero immediately; `end` holds zero until the first boundary.
|
|
49
|
+
def jumpStart:boolean false
|
|
50
|
+
; False when `parse` was handed something it did not understand. The caller
|
|
51
|
+
; reports it: a timing function silently downgraded to linear is a bug you
|
|
52
|
+
; find by squinting at motion.
|
|
53
|
+
def ok:boolean true
|
|
54
|
+
|
|
55
|
+
Constructor () {
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
sfn cubic:EVGEasing (x1:double y1:double x2:double y2:double) {
|
|
59
|
+
def e (new EVGEasing())
|
|
60
|
+
e.kind = 0
|
|
61
|
+
e.x1 = x1
|
|
62
|
+
e.y1 = y1
|
|
63
|
+
e.x2 = x2
|
|
64
|
+
e.y2 = y2
|
|
65
|
+
return e
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
sfn linear:EVGEasing () {
|
|
69
|
+
return (EVGEasing.cubic(0.0 0.0 1.0 1.0))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
sfn steps:EVGEasing (count:int atStart:boolean) {
|
|
73
|
+
def e (new EVGEasing())
|
|
74
|
+
e.kind = 1
|
|
75
|
+
e.stepCount = count
|
|
76
|
+
if (count < 1) {
|
|
77
|
+
e.stepCount = 1
|
|
78
|
+
}
|
|
79
|
+
e.jumpStart = atStart
|
|
80
|
+
return e
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
; --- parsing ----------------------------------------------------------------
|
|
84
|
+
|
|
85
|
+
; The four keywords are cubic-beziers with the control points CSS names.
|
|
86
|
+
; `ease` is not symmetric — it leaves fast and arrives slowly — which is why
|
|
87
|
+
; it is the default and why a linear default feels mechanical beside it.
|
|
88
|
+
sfn parse:EVGEasing (text:string) {
|
|
89
|
+
def t:string (trim text)
|
|
90
|
+
if ((strlen t) == 0) {
|
|
91
|
+
return (EVGEasing.linear())
|
|
92
|
+
}
|
|
93
|
+
if (t == "linear") { return (EVGEasing.cubic(0.0 0.0 1.0 1.0)) }
|
|
94
|
+
if (t == "ease") { return (EVGEasing.cubic(0.25 0.1 0.25 1.0)) }
|
|
95
|
+
if (t == "ease-in") { return (EVGEasing.cubic(0.42 0.0 1.0 1.0)) }
|
|
96
|
+
if (t == "ease-out") { return (EVGEasing.cubic(0.0 0.0 0.58 1.0)) }
|
|
97
|
+
if (t == "ease-in-out") { return (EVGEasing.cubic(0.42 0.0 0.58 1.0)) }
|
|
98
|
+
; `step-start` and `step-end` are the one-step shorthands.
|
|
99
|
+
if (t == "step-start") { return (EVGEasing.steps(1 true)) }
|
|
100
|
+
if (t == "step-end") { return (EVGEasing.steps(1 false)) }
|
|
101
|
+
|
|
102
|
+
def args:string (EVGEasing.argsOf(t "cubic-bezier"))
|
|
103
|
+
if ((strlen args) > 0) {
|
|
104
|
+
def nums:[double] (EVGEasing.numbers(args))
|
|
105
|
+
if ((array_length nums) == 4) {
|
|
106
|
+
; x has to stay inside [0,1] — the curve is a function of the
|
|
107
|
+
; input progress and a control point outside that range would
|
|
108
|
+
; make it fold back on itself. y is free, and a y outside [0,1]
|
|
109
|
+
; is the overshoot that makes a bounce.
|
|
110
|
+
def cx1:double (EVGEasing.clamp01((itemAt nums 0)))
|
|
111
|
+
def cx2:double (EVGEasing.clamp01((itemAt nums 2)))
|
|
112
|
+
return (EVGEasing.cubic(cx1 (itemAt nums 1) cx2 (itemAt nums 3)))
|
|
113
|
+
}
|
|
114
|
+
def bad:EVGEasing (EVGEasing.linear())
|
|
115
|
+
bad.ok = false
|
|
116
|
+
return bad
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
def sargs:string (EVGEasing.argsOf(t "steps"))
|
|
120
|
+
if ((strlen sargs) > 0) {
|
|
121
|
+
def parts:[string] (EVGEasing.splitTop(sargs 44))
|
|
122
|
+
def countTxt:string (trim (itemAt parts 0))
|
|
123
|
+
def n@(optional):double (to_double countTxt)
|
|
124
|
+
if n {
|
|
125
|
+
def atStart:boolean false
|
|
126
|
+
if ((array_length parts) > 1) {
|
|
127
|
+
def word:string (trim (itemAt parts 1))
|
|
128
|
+
if ((word == "start") || (word == "jump-start")) {
|
|
129
|
+
atStart = true
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return (EVGEasing.steps((to_int (unwrap n)) atStart))
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
def unknown:EVGEasing (EVGEasing.linear())
|
|
137
|
+
unknown.ok = false
|
|
138
|
+
return unknown
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
; Does this token look like a timing function at all? The transition
|
|
142
|
+
; shorthand is order-tolerant about everything except its two times, so
|
|
143
|
+
; telling a function from a duration is how the parts get sorted.
|
|
144
|
+
sfn looksLikeFunction:boolean (text:string) {
|
|
145
|
+
def t:string (trim text)
|
|
146
|
+
if (t == "linear") { return true }
|
|
147
|
+
if (t == "ease") { return true }
|
|
148
|
+
if (t == "ease-in") { return true }
|
|
149
|
+
if (t == "ease-out") { return true }
|
|
150
|
+
if (t == "ease-in-out") { return true }
|
|
151
|
+
if (t == "step-start") { return true }
|
|
152
|
+
if (t == "step-end") { return true }
|
|
153
|
+
if ((strlen (EVGEasing.argsOf(t "cubic-bezier"))) > 0) { return true }
|
|
154
|
+
if ((strlen (EVGEasing.argsOf(t "steps"))) > 0) { return true }
|
|
155
|
+
; Anything else shaped like a call is an ATTEMPTED timing function, and
|
|
156
|
+
; claiming it here is deliberate: `spring(1, 2)` then reaches `parse`,
|
|
157
|
+
; which reports it. Refusing to recognise it instead makes the shorthand
|
|
158
|
+
; parser mistake it for a property name and drop it in silence, and the
|
|
159
|
+
; author gets linear motion with nothing anywhere saying why. No CSS
|
|
160
|
+
; property name contains parentheses, so there is nothing to lose.
|
|
161
|
+
def n:int (strlen t)
|
|
162
|
+
if (n > 2) {
|
|
163
|
+
if ((charAt t (n - 1)) == 41) {
|
|
164
|
+
def i:int 0
|
|
165
|
+
while (i < n) {
|
|
166
|
+
if ((charAt t i) == 40) {
|
|
167
|
+
return true
|
|
168
|
+
}
|
|
169
|
+
i = (i + 1)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return false
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
; The inside of `name( ... )`, or "" when `t` is not that call.
|
|
177
|
+
sfn argsOf:string (t:string name:string) {
|
|
178
|
+
def nl:int (strlen name)
|
|
179
|
+
def tl:int (strlen t)
|
|
180
|
+
if (tl < (nl + 3)) {
|
|
181
|
+
return ""
|
|
182
|
+
}
|
|
183
|
+
if ((substring t 0 nl) != name) {
|
|
184
|
+
return ""
|
|
185
|
+
}
|
|
186
|
+
if ((charAt t nl) != 40) {
|
|
187
|
+
return ""
|
|
188
|
+
}
|
|
189
|
+
if ((charAt t (tl - 1)) != 41) {
|
|
190
|
+
return ""
|
|
191
|
+
}
|
|
192
|
+
return (substring t (nl + 1) (tl - 1))
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
sfn numbers:[double] (s:string) {
|
|
196
|
+
def out:[double]
|
|
197
|
+
def parts:[string] (EVGEasing.splitTop(s 44))
|
|
198
|
+
def i:int 0
|
|
199
|
+
while (i < (array_length parts)) {
|
|
200
|
+
def v@(optional):double (to_double (trim (itemAt parts i)))
|
|
201
|
+
if v {
|
|
202
|
+
push out (unwrap v)
|
|
203
|
+
}
|
|
204
|
+
i = (i + 1)
|
|
205
|
+
}
|
|
206
|
+
return out
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
; Split on `ch`, but only OUTSIDE parentheses. `cubic-bezier(0.25, 0.1,
|
|
210
|
+
; 0.25, 1)` inside a comma-separated transition list is why: splitting the
|
|
211
|
+
; list on every comma tears the function into four meaningless fragments,
|
|
212
|
+
; and the failure is silent because each fragment still parses as something.
|
|
213
|
+
sfn splitTop:[string] (s:string ch:int) {
|
|
214
|
+
def out:[string]
|
|
215
|
+
def depth:int 0
|
|
216
|
+
def start:int 0
|
|
217
|
+
def i:int 0
|
|
218
|
+
def n:int (strlen s)
|
|
219
|
+
while (i < n) {
|
|
220
|
+
def c:int (charAt s i)
|
|
221
|
+
if (c == 40) { depth = (depth + 1) }
|
|
222
|
+
if (c == 41) { depth = (depth - 1) }
|
|
223
|
+
if ((c == ch) && (depth == 0)) {
|
|
224
|
+
push out (substring s start i)
|
|
225
|
+
start = (i + 1)
|
|
226
|
+
}
|
|
227
|
+
i = (i + 1)
|
|
228
|
+
}
|
|
229
|
+
push out (substring s start n)
|
|
230
|
+
return out
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
; Whitespace-separated words, outside parentheses for the same reason:
|
|
234
|
+
; `steps(4, end)` is ONE word of the shorthand and has a space in it.
|
|
235
|
+
sfn splitWordsTop:[string] (s:string) {
|
|
236
|
+
def out:[string]
|
|
237
|
+
def depth:int 0
|
|
238
|
+
def start:int 0
|
|
239
|
+
def i:int 0
|
|
240
|
+
def n:int (strlen s)
|
|
241
|
+
while (i < n) {
|
|
242
|
+
def c:int (charAt s i)
|
|
243
|
+
if (c == 40) { depth = (depth + 1) }
|
|
244
|
+
if (c == 41) { depth = (depth - 1) }
|
|
245
|
+
def isSpace:boolean (((c == 32) || (c == 9)) || (c == 10))
|
|
246
|
+
if (isSpace && (depth == 0)) {
|
|
247
|
+
if (i > start) {
|
|
248
|
+
push out (substring s start i)
|
|
249
|
+
}
|
|
250
|
+
start = (i + 1)
|
|
251
|
+
}
|
|
252
|
+
i = (i + 1)
|
|
253
|
+
}
|
|
254
|
+
if (n > start) {
|
|
255
|
+
push out (substring s start n)
|
|
256
|
+
}
|
|
257
|
+
return out
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
sfn clamp01:double (v:double) {
|
|
261
|
+
if (v < 0.0) { return 0.0 }
|
|
262
|
+
if (v > 1.0) { return 1.0 }
|
|
263
|
+
return v
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
; --- evaluation --------------------------------------------------------------
|
|
267
|
+
|
|
268
|
+
; Input progress in, output progress out.
|
|
269
|
+
fn ease:double (t:double) {
|
|
270
|
+
def x:double t
|
|
271
|
+
if (x < 0.0) { x = 0.0 }
|
|
272
|
+
if (x > 1.0) { x = 1.0 }
|
|
273
|
+
if (kind == 1) {
|
|
274
|
+
return (this.stepAt(x))
|
|
275
|
+
}
|
|
276
|
+
; The identity curve is worth short-circuiting: `linear` is the most
|
|
277
|
+
; common easing there is and solving a cubic to be told t = t is waste
|
|
278
|
+
; on every element of every frame.
|
|
279
|
+
if ((((x1 == 0.0) && (y1 == 0.0)) && (x2 == 1.0)) && (y2 == 1.0)) {
|
|
280
|
+
return x
|
|
281
|
+
}
|
|
282
|
+
return (this.sampleY((this.solveT(x))))
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
fn stepAt:double (x:double) {
|
|
286
|
+
def n:double (to_double stepCount)
|
|
287
|
+
def raw:double (x * n)
|
|
288
|
+
def k:int (floor raw)
|
|
289
|
+
if jumpStart {
|
|
290
|
+
k = (k + 1)
|
|
291
|
+
}
|
|
292
|
+
def v:double ((to_double k) / n)
|
|
293
|
+
if (v < 0.0) { return 0.0 }
|
|
294
|
+
if (v > 1.0) { return 1.0 }
|
|
295
|
+
return v
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
; The polynomial form of a cubic Bézier with endpoints pinned at 0 and 1.
|
|
299
|
+
; Writing it out beats evaluating the Bernstein basis three times a frame.
|
|
300
|
+
fn sampleX:double (t:double) {
|
|
301
|
+
def cx:double (3.0 * x1)
|
|
302
|
+
def bx:double (((3.0 * (x2 - x1))) - cx)
|
|
303
|
+
def a:double ((1.0 - cx) - bx)
|
|
304
|
+
return (((((a * t) + bx) * t) + cx) * t)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
fn sampleY:double (t:double) {
|
|
308
|
+
def cy:double (3.0 * y1)
|
|
309
|
+
def by:double (((3.0 * (y2 - y1))) - cy)
|
|
310
|
+
def a:double ((1.0 - cy) - by)
|
|
311
|
+
return (((((a * t) + by) * t) + cy) * t)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
fn slopeX:double (t:double) {
|
|
315
|
+
def cx:double (3.0 * x1)
|
|
316
|
+
def bx:double (((3.0 * (x2 - x1))) - cx)
|
|
317
|
+
def a:double ((1.0 - cx) - bx)
|
|
318
|
+
return (((((3.0 * a) * t) + (2.0 * bx)) * t) + cx)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
; Find the curve parameter whose x is the input progress.
|
|
322
|
+
;
|
|
323
|
+
; Newton first, from t = x, which is already close because x is monotonic
|
|
324
|
+
; from 0 to 1. Where the derivative is near zero — which happens exactly
|
|
325
|
+
; where a control point has been pushed outside [0,1] to make an overshoot —
|
|
326
|
+
; Newton either crawls or leaves the interval, so bisection takes over. It
|
|
327
|
+
; is slower and it always converges, and the combination is what keeps the
|
|
328
|
+
; error at 5e-6 across the whole range instead of only the easy part of it.
|
|
329
|
+
fn solveT:double (x:double) {
|
|
330
|
+
def t:double x
|
|
331
|
+
def i:int 0
|
|
332
|
+
while (i < 8) {
|
|
333
|
+
def err:double ((this.sampleX(t)) - x)
|
|
334
|
+
if ((fabs err) < 0.0000001) {
|
|
335
|
+
return t
|
|
336
|
+
}
|
|
337
|
+
def d:double (this.slopeX(t))
|
|
338
|
+
if ((fabs d) < 0.000001) {
|
|
339
|
+
i = 8
|
|
340
|
+
} {
|
|
341
|
+
t = (t - (err / d))
|
|
342
|
+
if ((t < 0.0) || (t > 1.0)) {
|
|
343
|
+
i = 8
|
|
344
|
+
}
|
|
345
|
+
i = (i + 1)
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
def lo:double 0.0
|
|
349
|
+
def hi:double 1.0
|
|
350
|
+
def m:double x
|
|
351
|
+
if ((m < lo) || (m > hi)) {
|
|
352
|
+
m = 0.5
|
|
353
|
+
}
|
|
354
|
+
def j:int 0
|
|
355
|
+
while (j < 64) {
|
|
356
|
+
def v:double (this.sampleX(m))
|
|
357
|
+
if ((fabs (v - x)) < 0.0000001) {
|
|
358
|
+
return m
|
|
359
|
+
}
|
|
360
|
+
if (v < x) {
|
|
361
|
+
lo = m
|
|
362
|
+
} {
|
|
363
|
+
hi = m
|
|
364
|
+
}
|
|
365
|
+
m = ((lo + hi) / 2.0)
|
|
366
|
+
j = (j + 1)
|
|
367
|
+
}
|
|
368
|
+
return m
|
|
369
|
+
}
|
|
370
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; ==============================================================================
|
|
4
|
+
; EVGEffectTest — an effect that belongs to an ELEMENT, declared in the sheet
|
|
5
|
+
; ==============================================================================
|
|
6
|
+
;
|
|
7
|
+
; What `evg-surface-effect` used to mean: one post-process over the whole
|
|
8
|
+
; document, whose parameters were fields on EVGElement (`evg-ripple-speed` and
|
|
9
|
+
; thirteen siblings), and whose drops were pushed in by hand from the page's
|
|
10
|
+
; own `pointerdown` — every press, anywhere, rippled everything. Nothing in
|
|
11
|
+
; the document said WHICH box reacts or WHAT starts it, because there was
|
|
12
|
+
; nowhere to say it.
|
|
13
|
+
;
|
|
14
|
+
; What it means now, without disturbing any of that:
|
|
15
|
+
;
|
|
16
|
+
; evg-surface-effect: starfield WHAT runs. A string. The engine does not
|
|
17
|
+
; know what a starfield is and never will —
|
|
18
|
+
; the renderer's plugin does.
|
|
19
|
+
; evg-effect-on: press drag WHAT STARTS IT. The host's driver reads
|
|
20
|
+
; this; `always` is a thing that runs on its
|
|
21
|
+
; own clock.
|
|
22
|
+
; evg-fx-density: 2.6 PARAMETERS, under names this file has
|
|
23
|
+
; never heard of, carried through untouched.
|
|
24
|
+
;
|
|
25
|
+
; and WHERE is the element's own border box, because the layout already knows
|
|
26
|
+
; it. That is the whole of the change: three properties and a box, so that
|
|
27
|
+
; which element has the effect is a question the document answers.
|
|
28
|
+
;
|
|
29
|
+
; Everything below runs without a GPU. What the shader does with an instance
|
|
30
|
+
; is the painter's business; that the document produces the right instance is
|
|
31
|
+
; this file's.
|
|
32
|
+
; ==============================================================================
|
|
33
|
+
|
|
34
|
+
Import "EVGElement.rgr"
|
|
35
|
+
Import "EVGStyleSheet.rgr"
|
|
36
|
+
Import "EVGLayout.rgr"
|
|
37
|
+
Import "EVGDisplayList.rgr"
|
|
38
|
+
|
|
39
|
+
class FxCheck {
|
|
40
|
+
def passed:int 0
|
|
41
|
+
def failed:int 0
|
|
42
|
+
|
|
43
|
+
fn ok:void (name:string cond:boolean) {
|
|
44
|
+
if cond {
|
|
45
|
+
passed = (passed + 1)
|
|
46
|
+
print (" PASS " + name)
|
|
47
|
+
} {
|
|
48
|
+
failed = (failed + 1)
|
|
49
|
+
print (" FAIL " + name)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
fn has:void (name:string hay:string needle:string) {
|
|
54
|
+
def good:boolean ((indexOf hay needle) >= 0)
|
|
55
|
+
if (good == false) {
|
|
56
|
+
print (" looked for " + needle)
|
|
57
|
+
print (" in " + hay)
|
|
58
|
+
}
|
|
59
|
+
this.ok(name good)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
fn hasNot:void (name:string hay:string needle:string) {
|
|
63
|
+
def good:boolean ((indexOf hay needle) < 0)
|
|
64
|
+
if (good == false) {
|
|
65
|
+
print (" did not want " + needle)
|
|
66
|
+
print (" in " + hay)
|
|
67
|
+
}
|
|
68
|
+
this.ok(name good)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fn eqInt:void (name:string got:int want:int) {
|
|
72
|
+
def good:boolean (got == want)
|
|
73
|
+
if (good == false) {
|
|
74
|
+
print (" got " + (to_string got) + " want " + (to_string want))
|
|
75
|
+
}
|
|
76
|
+
this.ok(name good)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
fn eqStr:void (name:string got:string want:string) {
|
|
80
|
+
def good:boolean (got == want)
|
|
81
|
+
if (good == false) {
|
|
82
|
+
print (" got '" + got + "' want '" + want + "'")
|
|
83
|
+
}
|
|
84
|
+
this.ok(name good)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
class EVGEffectTest {
|
|
89
|
+
|
|
90
|
+
; A page with one card in it, styled by a sheet. The sheet is the point:
|
|
91
|
+
; an effect nobody can declare in CSS is an effect the application owns,
|
|
92
|
+
; which is what this replaces.
|
|
93
|
+
sfn page:EVGElement (css:string) {
|
|
94
|
+
def root (new EVGElement())
|
|
95
|
+
root.setAttribute("width" "400px")
|
|
96
|
+
root.setAttribute("height" "300px")
|
|
97
|
+
def card (EVGElement.createDiv())
|
|
98
|
+
card.id = "sky"
|
|
99
|
+
card.className = "card"
|
|
100
|
+
card.setAttribute("width" "200px")
|
|
101
|
+
card.setAttribute("height" "120px")
|
|
102
|
+
root.addChild(card)
|
|
103
|
+
if ((strlen css) > 0) {
|
|
104
|
+
def sheet (new EVGStyleSheet())
|
|
105
|
+
sheet.parse(css)
|
|
106
|
+
sheet.setViewport(400.0 300.0 false)
|
|
107
|
+
sheet.applyTree(root "")
|
|
108
|
+
}
|
|
109
|
+
return root
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
sfn listOf:EVGDisplayList (root:EVGElement) {
|
|
113
|
+
def lay (new EVGLayout())
|
|
114
|
+
lay.setPageSize(400.0 300.0)
|
|
115
|
+
lay.layout(root)
|
|
116
|
+
def dl (new EVGDisplayList())
|
|
117
|
+
dl.setTextEngine((lay.getTextEngine()))
|
|
118
|
+
dl.build(root)
|
|
119
|
+
return dl
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
sfn jsonOf:string (root:EVGElement) {
|
|
123
|
+
def dl:EVGDisplayList (EVGEffectTest.listOf(root))
|
|
124
|
+
return (dl.toJson())
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
; --- the declaration ------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
sfn testDeclared:void (c:FxCheck) {
|
|
130
|
+
print "-- the sheet says which element has the effect"
|
|
131
|
+
def css:string (".card { evg-surface-effect: starfield;"
|
|
132
|
+
+ " evg-effect-on: always;"
|
|
133
|
+
+ " evg-fx-density: 2.6;"
|
|
134
|
+
+ " evg-fx-drift: 0.4 }")
|
|
135
|
+
def root:EVGElement (EVGEffectTest.page(css))
|
|
136
|
+
def dl:EVGDisplayList (EVGEffectTest.listOf(root))
|
|
137
|
+
c.eqInt("one instance, for the one element that asked" (array_length dl.fxIds) 1)
|
|
138
|
+
c.eqStr("named by the element's own id" (itemAt dl.fxIds 0) "sky")
|
|
139
|
+
c.eqStr("carrying the kind verbatim" (itemAt dl.fxKinds 0) "starfield")
|
|
140
|
+
c.eqStr("and the trigger" (itemAt dl.fxTriggers 0) "always")
|
|
141
|
+
|
|
142
|
+
; THE BOX IS THE LAYOUT'S, not a rectangle somebody typed. This is the
|
|
143
|
+
; difference between an effect on an element and an effect on a page
|
|
144
|
+
; that happens to have an element on it.
|
|
145
|
+
c.ok("the box is the card's own width" ((itemAt dl.fxW 0) == 200.0))
|
|
146
|
+
c.ok("and its height" ((itemAt dl.fxH 0) == 120.0))
|
|
147
|
+
|
|
148
|
+
def js:string (dl.toJson())
|
|
149
|
+
c.has("the JSON carries the instance" js "\"kind\":\"starfield\"")
|
|
150
|
+
c.has("with its box" js "\"box\":[0.00,0.00,200.00,120.00]")
|
|
151
|
+
c.has("a parameter this engine has never heard of" js "\"density\":2.60")
|
|
152
|
+
c.has("and another" js "\"drift\":0.40")
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
; --- the link into paint order --------------------------------------------
|
|
156
|
+
|
|
157
|
+
sfn testPaintOrder:void (c:FxCheck) {
|
|
158
|
+
print "-- the effect is anchored where the element paints"
|
|
159
|
+
; No background: the card draws nothing of its own, and the effect
|
|
160
|
+
; still needs a place in the command stream, because paint order is
|
|
161
|
+
; the only thing that says whether a starfield is behind the text on
|
|
162
|
+
; the card or over it.
|
|
163
|
+
def css:string ".card { evg-surface-effect: starfield }"
|
|
164
|
+
def root:EVGElement (EVGEffectTest.page(css))
|
|
165
|
+
def js:string (EVGEffectTest.jsonOf(root))
|
|
166
|
+
c.has("a carrier rectangle names the instance" js "\"efx\":\"sky\"")
|
|
167
|
+
|
|
168
|
+
; And with a background, it rides that rectangle rather than adding a
|
|
169
|
+
; second one.
|
|
170
|
+
def css2:string ".card { background-color: rgb(10,12,30); evg-surface-effect: starfield }"
|
|
171
|
+
def root2:EVGElement (EVGEffectTest.page(css2))
|
|
172
|
+
def dl2:EVGDisplayList (EVGEffectTest.listOf(root2))
|
|
173
|
+
def named:int 0
|
|
174
|
+
def i:int 0
|
|
175
|
+
while (i < (array_length dl2.cmds)) {
|
|
176
|
+
def cmd:EVGDrawCmd (itemAt dl2.cmds i)
|
|
177
|
+
if ((strlen cmd.effectId) > 0) {
|
|
178
|
+
named = (named + 1)
|
|
179
|
+
}
|
|
180
|
+
i = (i + 1)
|
|
181
|
+
}
|
|
182
|
+
c.eqInt("one rectangle carries it, not two" named 1)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
; --- the ripple, through the general channel ------------------------------
|
|
186
|
+
|
|
187
|
+
sfn testRippleParams:void (c:FxCheck) {
|
|
188
|
+
print "-- an element-scoped ripple keeps its own property names"
|
|
189
|
+
; `evg-ripple-speed` predates all of this. An element-scoped ripple
|
|
190
|
+
; reads the same numbers as generic parameters, so a page that already
|
|
191
|
+
; styles a ripple does not learn a second spelling.
|
|
192
|
+
def css:string (".card { evg-surface-effect: ripple;"
|
|
193
|
+
+ " evg-effect-on: press drag;"
|
|
194
|
+
+ " evg-ripple-speed: 300;"
|
|
195
|
+
+ " evg-fx-strength: 11 }")
|
|
196
|
+
def root:EVGElement (EVGEffectTest.page(css))
|
|
197
|
+
def js:string (EVGEffectTest.jsonOf(root))
|
|
198
|
+
c.has("the ripple's own property arrives as a parameter" js "\"speed\":300.00")
|
|
199
|
+
c.has("the defaults come with it" js "\"gloss\":120.00")
|
|
200
|
+
c.has("what the page wrote under evg-fx- wins" js "\"strength\":11.00")
|
|
201
|
+
c.has("and the trigger is a list" js "\"on\":\"press drag\"")
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
; --- a page with no effect on it ------------------------------------------
|
|
205
|
+
|
|
206
|
+
sfn testSilence:void (c:FxCheck) {
|
|
207
|
+
print "-- a page with no effect writes nothing new"
|
|
208
|
+
def root:EVGElement (EVGEffectTest.page(".card { background-color: rgb(1,2,3) }"))
|
|
209
|
+
def js:string (EVGEffectTest.jsonOf(root))
|
|
210
|
+
c.hasNot("no effects array" js "\"effects\":")
|
|
211
|
+
c.hasNot("and no fx on any command" js "\"efx\":")
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
; --- the old whole-surface effect is untouched ----------------------------
|
|
215
|
+
|
|
216
|
+
sfn testLegacy:void (c:FxCheck) {
|
|
217
|
+
print "-- and the original whole-surface effect still works"
|
|
218
|
+
def root:EVGElement (EVGEffectTest.page(""))
|
|
219
|
+
root.setAttribute("evg-surface-effect" "ripple")
|
|
220
|
+
def xs:[double]
|
|
221
|
+
def ys:[double]
|
|
222
|
+
def ages:[double]
|
|
223
|
+
push xs 40.0
|
|
224
|
+
push ys 60.0
|
|
225
|
+
push ages 0.25
|
|
226
|
+
root.rippleXs = xs
|
|
227
|
+
root.rippleYs = ys
|
|
228
|
+
root.rippleAges = ages
|
|
229
|
+
def js:string (EVGEffectTest.jsonOf(root))
|
|
230
|
+
c.has("the document-wide effect is written as it always was" js "\"effect\":{\"kind\":\"ripple\"")
|
|
231
|
+
c.has("with the application's drops on it" js "[40.00,60.00,0.25]")
|
|
232
|
+
; It is ALSO an instance now — the root is an element like any other,
|
|
233
|
+
; and a host that reads instances sees it without the page changing.
|
|
234
|
+
c.has("and it is an instance too" js "\"kind\":\"ripple\"")
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
sfn main:void () {
|
|
238
|
+
def c (new FxCheck())
|
|
239
|
+
print "=== EVG element-scoped surface effects ==="
|
|
240
|
+
EVGEffectTest.testDeclared(c)
|
|
241
|
+
EVGEffectTest.testPaintOrder(c)
|
|
242
|
+
EVGEffectTest.testRippleParams(c)
|
|
243
|
+
EVGEffectTest.testSilence(c)
|
|
244
|
+
EVGEffectTest.testLegacy(c)
|
|
245
|
+
print ""
|
|
246
|
+
print ("passed=" + (to_string c.passed) + " failed=" + (to_string c.failed))
|
|
247
|
+
if (c.failed > 0) {
|
|
248
|
+
print "FAILURES"
|
|
249
|
+
} {
|
|
250
|
+
print "ALL PASS"
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|