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,230 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# The four verbs, against the fixtures. Guards the CLI itself: EVGPatch has a
|
|
4
|
+
# suite, but nothing else would notice a verb that stopped parsing its flags,
|
|
5
|
+
# printed the compiler's chatter onto stdout, or quietly found nothing.
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
here=$(cd "$(dirname "$0")" && pwd)
|
|
9
|
+
root=$(cd "$here/../../.." && pwd)
|
|
10
|
+
cd "$root"
|
|
11
|
+
work=$(mktemp -d)
|
|
12
|
+
trap 'rm -rf "$work"' EXIT
|
|
13
|
+
|
|
14
|
+
fail() { echo "SMOKE FAIL: $1" >&2; exit 1; }
|
|
15
|
+
|
|
16
|
+
# outline: every node, and the truncation notice when there is more
|
|
17
|
+
out=$(npm run --silent agent -- outline lib/evg/agent/fixtures/card.evg.json)
|
|
18
|
+
echo "$out" | grep -q '0/0/k:title' || fail "outline lost the keyed path"
|
|
19
|
+
echo "$out" | grep -q 'Orders' || fail "outline lost the text"
|
|
20
|
+
npm run --silent agent -- outline lib/evg/agent/fixtures/card.evg.json --depth=1 \
|
|
21
|
+
| grep -q 'deeper nodes not shown' || fail "outline truncated in silence"
|
|
22
|
+
|
|
23
|
+
# query: JSON, and only the two cards
|
|
24
|
+
npm run --silent agent -- query lib/evg/agent/fixtures/card.evg.json .card \
|
|
25
|
+
| grep -q '"count":2' || fail "query did not find both cards"
|
|
26
|
+
|
|
27
|
+
# measure: finds all four defects in the broken fixture, and none in the good one
|
|
28
|
+
found=$(npm run --silent agent -- measure lib/evg/agent/fixtures/broken.evg.json --width=600 --height=300)
|
|
29
|
+
echo "$found" | grep -q '"count":4' || fail "measure did not find the four defects: $found"
|
|
30
|
+
npm run --silent agent -- measure lib/evg/agent/fixtures/card.evg.json --width=600 --height=400 \
|
|
31
|
+
| grep -q '"count":0' || fail "measure reported a defect in a sound document"
|
|
32
|
+
|
|
33
|
+
# the numbers, not just the verdict: an overlap says by how much, and a sound
|
|
34
|
+
# document still says how much room is left under its content
|
|
35
|
+
echo "$found" | grep -q 'overlap by 100×40' || fail "overlap did not carry the amount: $found"
|
|
36
|
+
npm run --silent agent -- measure lib/evg/agent/fixtures/card.evg.json --width=600 --height=400 \
|
|
37
|
+
| grep -q '"bottomFree"' || fail "measure did not report the free space"
|
|
38
|
+
|
|
39
|
+
# a control somebody DREW. The fixture holds two switches that lay out the
|
|
40
|
+
# same: one made of boxes, one that says `role: switch`. The first is named
|
|
41
|
+
# with its path, the second is not — a document that declares what a node IS
|
|
42
|
+
# is the whole difference, and it is what a kit's control carries.
|
|
43
|
+
drawn=$(npm run --silent agent -- measure lib/evg/agent/fixtures/drawn.evg.json --width=390 --height=200)
|
|
44
|
+
echo "$drawn" | grep -q '"drawn"' || fail "measure did not notice a drawn switch: $drawn"
|
|
45
|
+
echo "$drawn" | grep -q '0/0/1: a pill with a knob' || fail "the drawn switch was not named by its path: $drawn"
|
|
46
|
+
echo "$drawn" | grep -q '0/1/0: a pill' && fail "a control that declares its role was reported as drawn: $drawn"
|
|
47
|
+
echo "$drawn" | grep -q '0/2: a groove with a knob' || fail "measure did not notice a drawn slider: $drawn"
|
|
48
|
+
echo "$drawn" | grep -q '"count":0' || fail "a drawn control is not a layout defect and must not move count: $drawn"
|
|
49
|
+
|
|
50
|
+
# alignment: the defect every other check passes. A stack that shares no edge,
|
|
51
|
+
# and an overlay one padding to the right of the column it floats over.
|
|
52
|
+
cat > "$work/ragged.evg.json" <<'JSON'
|
|
53
|
+
{"evg":1,"root":{"tag":"div","props":{"display":"flex","width":"390px","height":"844px","padding-left":"16px","padding-right":"16px","gap":"8px"},"children":[
|
|
54
|
+
{"tag":"div","props":{"width":"200px","height":"40px","margin-left":"20px"}},
|
|
55
|
+
{"tag":"div","props":{"width":"200px","height":"40px","margin-left":"60px"}},
|
|
56
|
+
{"tag":"div","props":{"width":"200px","height":"40px","margin-left":"4px"}}
|
|
57
|
+
]}}
|
|
58
|
+
JSON
|
|
59
|
+
ragged=$(npm run --silent agent -- measure "$work/ragged.evg.json")
|
|
60
|
+
echo "$ragged" | grep -q '"count":0' || fail "the ragged fixture should have no DEFECT: $ragged"
|
|
61
|
+
echo "$ragged" | grep -q 'share no edge' || fail "measure did not notice the ragged column: $ragged"
|
|
62
|
+
|
|
63
|
+
# the overlay case: the column is tidy, the bar floating over it is one padding
|
|
64
|
+
# to the right, and every other check passes it
|
|
65
|
+
cat > "$work/bar.evg.json" <<'JSON'
|
|
66
|
+
{"evg":1,"root":{"tag":"div","props":{"display":"flex","width":"390px","height":"844px","padding-left":"16px","padding-right":"16px","gap":"8px"},"children":[
|
|
67
|
+
{"tag":"div","props":{"height":"40px"}},
|
|
68
|
+
{"tag":"div","props":{"height":"40px"}},
|
|
69
|
+
{"tag":"div","props":{"position":"absolute","left":"16px","bottom":"16px","width":"358px","height":"52px"}}
|
|
70
|
+
]}}
|
|
71
|
+
JSON
|
|
72
|
+
bar=$(npm run --silent agent -- measure "$work/bar.evg.json")
|
|
73
|
+
echo "$bar" | grep -q '"count":0' || fail "the overlay fixture should have no DEFECT: $bar"
|
|
74
|
+
echo "$bar" | grep -q 'one padding' \
|
|
75
|
+
|| fail "measure did not notice the overlay one padding off: $bar"
|
|
76
|
+
if npm run --silent agent -- measure lib/evg/agent/fixtures/card.evg.json | grep -q '"align"'; then
|
|
77
|
+
fail "a tidy document must not report alignment noise"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# --boxes: where each node really is, and how far the next one starts
|
|
81
|
+
boxes=$(npm run --silent agent -- measure lib/evg/agent/fixtures/card.evg.json --boxes --at=0)
|
|
82
|
+
echo "$boxes" | grep -q '"gapNext"' || fail "--boxes did not report a distance: $boxes"
|
|
83
|
+
echo "$boxes" | grep -q '"x":' || fail "--boxes did not report positions"
|
|
84
|
+
if npm run --silent agent -- measure lib/evg/agent/fixtures/card.evg.json | grep -q '"boxes"'; then
|
|
85
|
+
fail "boxes should cost nothing unless asked for"
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# patch: applies, writes, and the inverse puts it back
|
|
89
|
+
cp lib/evg/agent/fixtures/card.evg.json "$work/doc.json"
|
|
90
|
+
cat > "$work/ops.json" <<'JSON'
|
|
91
|
+
{"ops":[
|
|
92
|
+
{"op":"set-text","at":"0/0/k:title","value":"Invoices"},
|
|
93
|
+
{"op":"set-prop","at":"0/0","prop":"border-width","value":"1px"}
|
|
94
|
+
]}
|
|
95
|
+
JSON
|
|
96
|
+
npm run --silent agent -- patch "$work/doc.json" "$work/ops.json" | grep -q '"applied":2' \
|
|
97
|
+
|| fail "patch did not apply"
|
|
98
|
+
npm run --silent agent -- outline "$work/doc.json" | grep -q 'Invoices' || fail "the edit did not land"
|
|
99
|
+
|
|
100
|
+
# patch answers with the layout it produced, without being asked: an agent that
|
|
101
|
+
# patches and stops has changed a picture it cannot see
|
|
102
|
+
cat > "$work/tint.json" <<'JSON'
|
|
103
|
+
{"ops":[
|
|
104
|
+
{"op":"set-prop","at":"0/0","prop":"background-color","value":"rgb(255,251,235)"}
|
|
105
|
+
]}
|
|
106
|
+
JSON
|
|
107
|
+
cp lib/evg/agent/fixtures/broken.evg.json "$work/broken.json"
|
|
108
|
+
told=$(npm run --silent agent -- patch "$work/broken.json" "$work/tint.json")
|
|
109
|
+
echo "$told" | grep -q '"layout"' || fail "patch did not report the layout: $told"
|
|
110
|
+
echo "$told" | grep -q 'overlap by' \
|
|
111
|
+
|| fail "patch did not name the defect in the document it just wrote: $told"
|
|
112
|
+
echo "$told" | grep -q '"count":4' \
|
|
113
|
+
|| fail "patch's layout count is not the measure's: $told"
|
|
114
|
+
|
|
115
|
+
cat > "$work/undo.json" <<'JSON'
|
|
116
|
+
{"ops":[
|
|
117
|
+
{"op":"set-prop","at":"0/0","prop":"border-width","value":""},
|
|
118
|
+
{"op":"set-text","at":"0/0/k:title","value":"Orders"}
|
|
119
|
+
]}
|
|
120
|
+
JSON
|
|
121
|
+
npm run --silent agent -- patch "$work/doc.json" "$work/undo.json" > /dev/null
|
|
122
|
+
npm run --silent agent -- outline "$work/doc.json" > "$work/after.txt"
|
|
123
|
+
cp lib/evg/agent/fixtures/card.evg.json "$work/orig.json"
|
|
124
|
+
npm run --silent agent -- outline "$work/orig.json" > "$work/before.txt"
|
|
125
|
+
diff -q "$work/before.txt" "$work/after.txt" > /dev/null || fail "the inverse did not restore the document"
|
|
126
|
+
|
|
127
|
+
# an op that lands on the tag default: applied, absent from the file, and SAID
|
|
128
|
+
# so. EVG divs are flex-direction: column, so setting column on one removes the
|
|
129
|
+
# line rather than adding it, and an agent that only re-reads the file decides
|
|
130
|
+
# the tool dropped its edit.
|
|
131
|
+
cat > "$work/dflt.json" <<'JSON'
|
|
132
|
+
{"ops":[
|
|
133
|
+
{"op":"set-prop","at":"0/0","prop":"flex-direction","value":"column"}
|
|
134
|
+
]}
|
|
135
|
+
JSON
|
|
136
|
+
said=$(npm run --silent agent -- patch "$work/doc.json" "$work/dflt.json")
|
|
137
|
+
echo "$said" | grep -q '"atDefault"' || fail "patch did not report the default-valued op: $said"
|
|
138
|
+
echo "$said" | grep -q '"prop":"flex-direction"' || fail "atDefault did not name the property"
|
|
139
|
+
if npm run --silent agent -- outline "$work/doc.json" | grep -q 'flex-direction=column'; then
|
|
140
|
+
fail "a default should not be written — the note is what carries it"
|
|
141
|
+
fi
|
|
142
|
+
cat > "$work/back.json" <<'JSON'
|
|
143
|
+
{"ops":[
|
|
144
|
+
{"op":"set-prop","at":"0/0","prop":"flex-direction","value":"row"}
|
|
145
|
+
]}
|
|
146
|
+
JSON
|
|
147
|
+
if npm run --silent agent -- patch "$work/doc.json" "$work/back.json" | grep -q '"atDefault"'; then
|
|
148
|
+
fail "a value that is not the default must not be reported as one"
|
|
149
|
+
fi
|
|
150
|
+
npm run --silent agent -- outline "$work/doc.json" | grep -q 'flex-direction=row' \
|
|
151
|
+
|| fail "a non-default flex-direction did not survive the write"
|
|
152
|
+
cp lib/evg/agent/fixtures/card.evg.json "$work/doc.json"
|
|
153
|
+
|
|
154
|
+
# a rejected op leaves the document alone
|
|
155
|
+
cat > "$work/bad.json" <<'JSON'
|
|
156
|
+
{"ops":[
|
|
157
|
+
{"op":"set-prop","at":"0/0","prop":"border-width","value":"2px"},
|
|
158
|
+
{"op":"set-prop","at":"0/0","prop":"aspect-ratio","value":"16/9"}
|
|
159
|
+
]}
|
|
160
|
+
JSON
|
|
161
|
+
npm run --silent agent -- patch "$work/doc.json" "$work/bad.json" | grep -q '"ok":false' \
|
|
162
|
+
|| fail "an unknown property was accepted"
|
|
163
|
+
npm run --silent agent -- outline "$work/doc.json" > "$work/unchanged.txt"
|
|
164
|
+
diff -q "$work/before.txt" "$work/unchanged.txt" > /dev/null \
|
|
165
|
+
|| fail "a rejected batch still changed the document"
|
|
166
|
+
|
|
167
|
+
# a bitmap, through the tracer and into the document. The picture must arrive
|
|
168
|
+
# as vector the document can hold, and the palette must be countable — an agent
|
|
169
|
+
# that cannot see the photograph has to be able to theme a screen from it.
|
|
170
|
+
if [ ! -f lib/evg/bin/evg_image_tool.js ]; then
|
|
171
|
+
echo "building evg_image_tool…"
|
|
172
|
+
npm run --silent agent:image > "$work/image-build.log" 2>&1 \
|
|
173
|
+
|| { tail -20 "$work/image-build.log"; fail "could not build evg_image_tool"; }
|
|
174
|
+
fi
|
|
175
|
+
cp lib/evg/web/tracer/sample.png "$work/shot.png"
|
|
176
|
+
traced=$(cd "$work" && node "$root/lib/evg/bin/evg_image_tool.js" shot.png --out=shot --width=180)
|
|
177
|
+
echo "$traced" | grep -q '"colors"' || fail "the tracer reported no palette: $traced"
|
|
178
|
+
echo "$traced" | grep -q '"share"' || fail "the palette has no shares: $traced"
|
|
179
|
+
[ -f "$work/shot.svg" ] || fail "no traced SVG"
|
|
180
|
+
[ -f "$work/shot.ops.json" ] || fail "no ops file to insert the picture with"
|
|
181
|
+
cp lib/evg/agent/fixtures/card.evg.json "$work/pic.json"
|
|
182
|
+
npm run --silent agent -- patch "$work/pic.json" "$work/shot.ops.json" | grep -q '"ok":true' \
|
|
183
|
+
|| fail "the traced picture would not apply"
|
|
184
|
+
npm run --silent agent -- outline "$work/pic.json" | grep -q '^0/0 *svg' \
|
|
185
|
+
|| fail "the picture is not in the document as an svg node"
|
|
186
|
+
|
|
187
|
+
# a two-stop gradient, which EVG spells two ways and the painters used to know
|
|
188
|
+
# only one of: `gradient-from` / `gradient-to` is what the display list, the GPU
|
|
189
|
+
# backend and the Figma importer all speak, and it drew on the GPU and nowhere
|
|
190
|
+
# else. A flat render means the pair is being ignored again.
|
|
191
|
+
npm run --silent agent:render -- lib/evg/agent/fixtures/gradient.evg.json "$work/grad.png" -w 400 -h 260 > /dev/null 2>&1
|
|
192
|
+
[ -f "$work/grad.png" ] || fail "the gradient fixture did not render"
|
|
193
|
+
distinct=$(node -e '
|
|
194
|
+
const fs=require("fs"),zlib=require("zlib");
|
|
195
|
+
const d=fs.readFileSync(process.argv[1]);
|
|
196
|
+
// walk the IDAT chunks, inflate, and count distinct colours on one scanline
|
|
197
|
+
let i=8,idat=[];
|
|
198
|
+
while(i<d.length){const len=d.readUInt32BE(i);const t=d.toString("latin1",i+4,i+8);
|
|
199
|
+
if(t==="IDAT")idat.push(d.subarray(i+8,i+8+len));i+=12+len;}
|
|
200
|
+
const raw=zlib.inflateSync(Buffer.concat(idat));
|
|
201
|
+
const w=d.readUInt32BE(16), stride=w*4+1, row=60;
|
|
202
|
+
const seen=new Set();
|
|
203
|
+
for(let x=30;x<170;x++){const o=row*stride+1+x*4;seen.add(raw[o]+","+raw[o+1]+","+raw[o+2]);}
|
|
204
|
+
console.log(seen.size);
|
|
205
|
+
' "$work/grad.png")
|
|
206
|
+
[ "$distinct" -gt 20 ] || fail "the gradient rendered as $distinct colour(s) across its width — a flat fill, not a gradient"
|
|
207
|
+
echo " gradient $distinct distinct colours across the band"
|
|
208
|
+
|
|
209
|
+
# a diagram, which is a different shape of document: everything absolutely
|
|
210
|
+
# positioned, every shape a path whose box is 0x0 and whose geometry is in `d`
|
|
211
|
+
if [ -f gallery/rangerflow/bin/rangerflow_demo.js ]; then
|
|
212
|
+
npm run --silent rangerflow:mermaid > /dev/null 2>&1 || fail "the mermaid demo did not run"
|
|
213
|
+
diagram=gallery/rangerflow/out/rangerflow-mermaid.evg.json
|
|
214
|
+
[ -f "$diagram" ] || fail "the mermaid demo wrote no editable document"
|
|
215
|
+
npm run --silent agent -- measure "$diagram" | grep -q '"count":0' \
|
|
216
|
+
|| fail "measure found a defect in a diagram RangerFlow laid out itself"
|
|
217
|
+
cp "$diagram" "$work/d.json"
|
|
218
|
+
cat > "$work/dops.json" <<'JSON'
|
|
219
|
+
{"ops":[{"op":"set-prop","at":"0/51","prop":"d","value":"M 1650 354 L 1732 354 L 1750 390 L 1668 390 Z"}]}
|
|
220
|
+
JSON
|
|
221
|
+
npm run --silent agent -- patch "$work/d.json" "$work/dops.json" | grep -q '"applied":1' \
|
|
222
|
+
|| fail "could not edit a path in a diagram"
|
|
223
|
+
npm run --silent agent -- measure "$work/d.json" | grep -q "past the page width" \
|
|
224
|
+
|| fail "a shape moved off the page was not reported — path bounds are not being read"
|
|
225
|
+
echo " diagram measured, edited, and the off-page shape reported"
|
|
226
|
+
else
|
|
227
|
+
echo " diagram skipped (rangerflow demo not built)"
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
echo "ALL PASS — outline, query, measure, patch, undo, rejection"
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# `lib/evg/android` — EVG's display list, on Android and on a JVM
|
|
2
|
+
|
|
3
|
+
The backend the Android ports share: an `EVGDisplayList` in, `android.graphics`
|
|
4
|
+
or Java2D out. No app lives here, and neither does any knowledge of one.
|
|
5
|
+
|
|
6
|
+
```text
|
|
7
|
+
EVGDisplayList ← eight command kinds, absolute pixels,
|
|
8
|
+
│ resolved colours. Whoever built it.
|
|
9
|
+
▼
|
|
10
|
+
EvgPainter ← the walk. Written once.
|
|
11
|
+
│
|
|
12
|
+
├── AndroidEvgSurface android.graphics.Canvas ← the app
|
|
13
|
+
├── AwtEvgSurface java.awt.Graphics2D ← the checks
|
|
14
|
+
└── RecordingSurface a tally, then one of the above
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
| Path | What it is |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `src/main/kotlin/…/EvgSurface.kt` | The eight things a backend has to draw |
|
|
20
|
+
| `src/main/kotlin/…/EvgPainter.kt` | Display list → surface calls |
|
|
21
|
+
| `src/main/kotlin/…/RecordingSurface.kt` | Counts what the painter dispatched, so coverage is a number |
|
|
22
|
+
| `src/main/kotlin/…/EvgEngineThread.kt` | The engine on its own thread: `post`, `ask`, `sync`, and frames coalesced and delivered through `View.post` — platform-free, so a JVM check can use it too |
|
|
23
|
+
| `src/android/kotlin/…/AndroidEvgSurface.kt` | `android.graphics` implementation, plus `FaceSet` and `ImageStore` |
|
|
24
|
+
| `src/android/kotlin/…/RippleEffect.kt` | `evg-surface-effect: ripple` as an AGSL post-process (API 33+) |
|
|
25
|
+
| `src/android/kotlin/…/AndroidTextMeasurer.kt` | Skia measures the text the layout is made with, through the `FaceSet` the surface paints with — installed above the app, so the first layout already has it |
|
|
26
|
+
| `src/awt/kotlin/…/AwtEvgSurface.kt` | The same surface on Java2D, so a port is testable without a device |
|
|
27
|
+
| `src/awt/kotlin/…/AwtTextMeasurer.kt` | The Java2D twin of the measurer, and `AwtFaces`, the one place a family becomes a `Font` for both the surface and the measurer |
|
|
28
|
+
| `androidstubs/` | Platform declarations, so a host type-checks with no SDK installed |
|
|
29
|
+
|
|
30
|
+
## Why it is source, not a library
|
|
31
|
+
|
|
32
|
+
A port compiles these files into its own build. That is not laziness about
|
|
33
|
+
publishing a `.aar`: the painter has to name the generated `EVGDisplayList`
|
|
34
|
+
type, and every port generates its own copy of EVG by compiling its own Ranger
|
|
35
|
+
tree. So the one thing the ports agree on is the **package** that generated code
|
|
36
|
+
goes into — `fi.ranger.rgr` — and the painter imports
|
|
37
|
+
`fi.ranger.rgr.EVGDisplayList` from there. Two apps, two compilations, one
|
|
38
|
+
import line, and no serialisation boundary in between.
|
|
39
|
+
|
|
40
|
+
Each port's `scripts/build-ranger.sh` puts that `package` line at the top of the
|
|
41
|
+
file the compiler wrote.
|
|
42
|
+
|
|
43
|
+
## Who uses it
|
|
44
|
+
|
|
45
|
+
* [`gallery/pptx/android`](../../../gallery/pptx/android/README.md) — the slide viewer.
|
|
46
|
+
Adds `TouchRouter`, a `SlideView` and the four bundled faces a deck was
|
|
47
|
+
measured with.
|
|
48
|
+
* [`gallery/ui/android`](../../../gallery/ui/android/README.md) — the dashboard demo. Adds
|
|
49
|
+
a viewport facade and a `DashboardView`, and draws with the platform's own
|
|
50
|
+
sans because that is what the page was laid out against.
|
|
51
|
+
* [`gallery/realtrainer/android`](../../../gallery/realtrainer/android/README.md) — the
|
|
52
|
+
RealTrainer demo. The page is the view rather than a fitted document, and
|
|
53
|
+
the host adds the soft keyboard through an `InputConnection`; the stubs
|
|
54
|
+
under `androidstubs/InputMethod.kt` are its.
|
|
55
|
+
|
|
56
|
+
All three are a facade in Ranger plus a `View`. That is the claim this directory
|
|
57
|
+
exists to make good on: the seam is the display list, so a new host is a page of
|
|
58
|
+
delegation rather than a second renderer.
|
|
59
|
+
|
|
60
|
+
## The one thing that is not a surface
|
|
61
|
+
|
|
62
|
+
`evg-surface-effect: ripple` is not a draw command and cannot be: it is a pass
|
|
63
|
+
over the finished pixels. `RippleEffect` is that pass on Android — the display
|
|
64
|
+
list's `effectKind` and its dozen `effect*` numbers, handed to a `RuntimeShader`
|
|
65
|
+
through `RenderEffect.createRuntimeShaderEffect`, which is the same stage
|
|
66
|
+
`evg-webgl.js` runs its own version in. It is a translation of that shader, not
|
|
67
|
+
a second one; API 33 and later, a no-op below.
|
|
68
|
+
|
|
69
|
+
## Scroll layers, and what this painter does not do yet
|
|
70
|
+
|
|
71
|
+
A clip that can scroll arrives with `layer` set on its PUSH_CLIP — see
|
|
72
|
+
`EVGDisplayList.refreshLayers`. An app that keeps its list across a scroll
|
|
73
|
+
hands the painter the SAME list, with the commands inside that clip already
|
|
74
|
+
moved to where the scroll put them, so `EvgPainter.paint` draws the right
|
|
75
|
+
frame without knowing a layer from any other clip. What the host saves is
|
|
76
|
+
the layout and the list build; what it still pays is rasterising every
|
|
77
|
+
command in the layer, every frame.
|
|
78
|
+
|
|
79
|
+
The next step, when a long page on a device asks for it, is the one the
|
|
80
|
+
browser painter took: keep what was made from the layer. Here that is a
|
|
81
|
+
`Bitmap` the size of the layer's range, painted once per `buildSeq` through
|
|
82
|
+
a `Canvas` over it, and drawn per frame at the layer's clip with
|
|
83
|
+
`layerShiftX/Y` subtracted from the shift it was painted at — a scroll
|
|
84
|
+
frame is then one `drawBitmap` under the clip and the commands outside the
|
|
85
|
+
layer. The list's `layerFirst`/`layerLast` give the command range; nothing
|
|
86
|
+
else in the list has to change.
|
|
87
|
+
|
|
88
|
+
## What the surfaces do not agree on
|
|
89
|
+
|
|
90
|
+
Both honour clipping and multi-ring even-odd paths, which the software
|
|
91
|
+
rasteriser drops. They differ in one place, and it is a platform fact rather
|
|
92
|
+
than a choice: a hardware-accelerated `Canvas` ignores `BlurMaskFilter`, so
|
|
93
|
+
`AndroidEvgSurface` **draws** a shadow's falloff — the silhouette a few times,
|
|
94
|
+
each pass grown and fainter — while `AwtEvgSurface` filters it. See the comment
|
|
95
|
+
on `canBlur`.
|
|
96
|
+
|
|
97
|
+
**License: AGPL-3.0-or-later** (Gallery).
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Compile-time stubs for the Android platform classes this host uses.
|
|
3
|
+
// ============================================================================
|
|
4
|
+
//
|
|
5
|
+
// `AndroidEvgSurface`, `SlideView` and `MainActivity` are the three files that
|
|
6
|
+
// cannot be checked without an Android SDK, and an SDK is a 600 MB download
|
|
7
|
+
// from a host that is not always reachable. These declarations are enough for
|
|
8
|
+
// `kotlinc` to TYPE-CHECK those three files: every member below is one this
|
|
9
|
+
// host actually calls, with the signature the platform gives it.
|
|
10
|
+
//
|
|
11
|
+
// They are never compiled into the APK and never packaged. The real
|
|
12
|
+
// `android.jar` is on the compile classpath of the Gradle build and wins there;
|
|
13
|
+
// this file exists only for `scripts/typecheck-host.sh`.
|
|
14
|
+
//
|
|
15
|
+
// What this proves: the host's Kotlin is well-formed, its overrides match, its
|
|
16
|
+
// types line up, and it calls nothing that does not exist. What it does not
|
|
17
|
+
// prove: that the platform's implementations behave as the host expects — a
|
|
18
|
+
// stub cannot draw. Treat a green typecheck as "it will compile", not as
|
|
19
|
+
// "it works".
|
|
20
|
+
//
|
|
21
|
+
// If a signature here disagrees with the SDK, the Gradle build is the one that
|
|
22
|
+
// is right and this file is the one to fix.
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
@file:Suppress("UNUSED_PARAMETER", "unused")
|
|
26
|
+
|
|
27
|
+
package android.graphics
|
|
28
|
+
|
|
29
|
+
class Bitmap {
|
|
30
|
+
@JvmField val width: Int = 0
|
|
31
|
+
@JvmField val height: Int = 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
object BitmapFactory {
|
|
35
|
+
fun decodeByteArray(data: ByteArray, offset: Int, length: Int): Bitmap? = null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
class BlurMaskFilter(radius: Float, style: Blur) : MaskFilter() {
|
|
39
|
+
enum class Blur { NORMAL, SOLID, OUTER, INNER }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
open class MaskFilter
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* `RuntimeShader` is AGSL — Skia's own shading language, handed to apps at API
|
|
46
|
+
* 33. The constructor compiles, and it THROWS on a program it cannot compile,
|
|
47
|
+
* which is why the host that builds one catches.
|
|
48
|
+
*/
|
|
49
|
+
class RuntimeShader(sksl: String) : Shader() {
|
|
50
|
+
fun setFloatUniform(name: String, value: Float) {}
|
|
51
|
+
fun setFloatUniform(name: String, a: Float, b: Float) {}
|
|
52
|
+
fun setFloatUniform(name: String, a: Float, b: Float, c: Float) {}
|
|
53
|
+
fun setFloatUniform(name: String, a: Float, b: Float, c: Float, d: Float) {}
|
|
54
|
+
fun setFloatUniform(name: String, values: FloatArray) {}
|
|
55
|
+
fun setIntUniform(name: String, value: Int) {}
|
|
56
|
+
fun setInputShader(name: String, shader: Shader) {}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* A post-process over a view's finished pixels. `createRuntimeShaderEffect`
|
|
61
|
+
* renders the view into a texture, binds it to the named `uniform shader`, and
|
|
62
|
+
* lets the program decide every pixel — the same stage the WebGL host runs its
|
|
63
|
+
* surface effects in.
|
|
64
|
+
*/
|
|
65
|
+
class RenderEffect {
|
|
66
|
+
companion object {
|
|
67
|
+
fun createRuntimeShaderEffect(shader: RuntimeShader, uniformShaderName: String): RenderEffect =
|
|
68
|
+
RenderEffect()
|
|
69
|
+
|
|
70
|
+
fun createBlurEffect(radiusX: Float, radiusY: Float, tile: Shader.TileMode): RenderEffect =
|
|
71
|
+
RenderEffect()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
open class Shader {
|
|
76
|
+
enum class TileMode { CLAMP, REPEAT, MIRROR }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
class LinearGradient(
|
|
80
|
+
x0: Float, y0: Float, x1: Float, y1: Float,
|
|
81
|
+
color0: Int, color1: Int, tile: Shader.TileMode,
|
|
82
|
+
) : Shader()
|
|
83
|
+
|
|
84
|
+
class Matrix {
|
|
85
|
+
fun setScale(sx: Float, sy: Float) {}
|
|
86
|
+
fun setScale(sx: Float, sy: Float, px: Float, py: Float) {}
|
|
87
|
+
fun postTranslate(dx: Float, dy: Float) {}
|
|
88
|
+
fun postConcat(other: Matrix) {}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
class RectF() {
|
|
92
|
+
constructor(src: RectF) : this()
|
|
93
|
+
fun set(l: Float, t: Float, r: Float, b: Float) {}
|
|
94
|
+
fun offset(dx: Float, dy: Float) {}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
class Path {
|
|
98
|
+
enum class FillType { WINDING, EVEN_ODD, INVERSE_WINDING, INVERSE_EVEN_ODD }
|
|
99
|
+
enum class Direction { CW, CCW }
|
|
100
|
+
|
|
101
|
+
var fillType: FillType = FillType.WINDING
|
|
102
|
+
fun reset() {}
|
|
103
|
+
fun moveTo(x: Float, y: Float) {}
|
|
104
|
+
fun lineTo(x: Float, y: Float) {}
|
|
105
|
+
fun close() {}
|
|
106
|
+
fun addRoundRect(rect: RectF, rx: Float, ry: Float, dir: Direction) {}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
class Typeface {
|
|
110
|
+
companion object {
|
|
111
|
+
val DEFAULT: Typeface = Typeface()
|
|
112
|
+
val DEFAULT_BOLD: Typeface = Typeface()
|
|
113
|
+
const val NORMAL = 0
|
|
114
|
+
const val BOLD = 1
|
|
115
|
+
const val ITALIC = 2
|
|
116
|
+
const val BOLD_ITALIC = 3
|
|
117
|
+
fun createFromFile(path: java.io.File): Typeface = Typeface()
|
|
118
|
+
fun create(family: Typeface?, style: Int): Typeface = Typeface()
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
object Color {
|
|
123
|
+
const val WHITE: Int = -1
|
|
124
|
+
fun alpha(color: Int): Int = 0
|
|
125
|
+
fun rgb(r: Int, g: Int, b: Int): Int = 0
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
class Paint() {
|
|
129
|
+
constructor(flags: Int) : this()
|
|
130
|
+
|
|
131
|
+
companion object {
|
|
132
|
+
const val ANTI_ALIAS_FLAG = 1
|
|
133
|
+
const val SUBPIXEL_TEXT_FLAG = 128
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
enum class Style { FILL, STROKE, FILL_AND_STROKE }
|
|
137
|
+
enum class Join { MITER, ROUND, BEVEL }
|
|
138
|
+
enum class Cap { BUTT, ROUND, SQUARE }
|
|
139
|
+
|
|
140
|
+
class FontMetrics {
|
|
141
|
+
@JvmField var ascent: Float = 0f
|
|
142
|
+
@JvmField var descent: Float = 0f
|
|
143
|
+
@JvmField var leading: Float = 0f
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
var color: Int = 0
|
|
147
|
+
var style: Style = Style.FILL
|
|
148
|
+
var shader: Shader? = null
|
|
149
|
+
var maskFilter: MaskFilter? = null
|
|
150
|
+
var strokeWidth: Float = 0f
|
|
151
|
+
var strokeJoin: Join = Join.MITER
|
|
152
|
+
var strokeCap: Cap = Cap.BUTT
|
|
153
|
+
var typeface: Typeface? = null
|
|
154
|
+
var textSize: Float = 0f
|
|
155
|
+
val fontMetrics: FontMetrics = FontMetrics()
|
|
156
|
+
fun measureText(text: String): Float = 0f
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
open class Canvas {
|
|
160
|
+
val isHardwareAccelerated: Boolean = false
|
|
161
|
+
fun save(): Int = 0
|
|
162
|
+
fun restore() {}
|
|
163
|
+
fun restoreToCount(count: Int) {}
|
|
164
|
+
fun clipRect(left: Float, top: Float, right: Float, bottom: Float): Boolean = true
|
|
165
|
+
fun clipPath(path: Path): Boolean = true
|
|
166
|
+
fun rotate(degrees: Float, px: Float, py: Float) {}
|
|
167
|
+
fun scale(sx: Float, sy: Float) {}
|
|
168
|
+
fun translate(dx: Float, dy: Float) {}
|
|
169
|
+
fun drawColor(color: Int) {}
|
|
170
|
+
fun drawRect(rect: RectF, paint: Paint) {}
|
|
171
|
+
fun drawRoundRect(rect: RectF, rx: Float, ry: Float, paint: Paint) {}
|
|
172
|
+
fun drawPath(path: Path, paint: Paint) {}
|
|
173
|
+
fun drawText(text: String, x: Float, y: Float, paint: Paint) {}
|
|
174
|
+
fun drawBitmap(bitmap: Bitmap, matrix: Matrix, paint: Paint?) {}
|
|
175
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Compile-time stub. See AndroidStubs.kt.
|
|
2
|
+
package android.annotation
|
|
3
|
+
|
|
4
|
+
@Target(
|
|
5
|
+
AnnotationTarget.FUNCTION,
|
|
6
|
+
AnnotationTarget.PROPERTY,
|
|
7
|
+
AnnotationTarget.CLASS,
|
|
8
|
+
AnnotationTarget.VALUE_PARAMETER,
|
|
9
|
+
)
|
|
10
|
+
annotation class SuppressLint(vararg val value: String)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Compile-time stub. See AndroidStubs.kt.
|
|
2
|
+
@file:Suppress("UNUSED_PARAMETER", "unused")
|
|
3
|
+
|
|
4
|
+
package android.app
|
|
5
|
+
|
|
6
|
+
import android.content.Context
|
|
7
|
+
import android.content.Intent
|
|
8
|
+
import android.os.Bundle
|
|
9
|
+
import android.view.Menu
|
|
10
|
+
import android.view.MenuItem
|
|
11
|
+
import android.view.View
|
|
12
|
+
|
|
13
|
+
open class Activity : Context() {
|
|
14
|
+
companion object {
|
|
15
|
+
const val RESULT_OK = -1
|
|
16
|
+
const val RESULT_CANCELED = 0
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
var title: CharSequence = ""
|
|
20
|
+
val intent: Intent? = null
|
|
21
|
+
|
|
22
|
+
protected open fun onCreate(savedInstanceState: Bundle?) {}
|
|
23
|
+
fun setContentView(view: View) {}
|
|
24
|
+
fun startActivityForResult(intent: Intent, requestCode: Int) {}
|
|
25
|
+
open fun onCreateOptionsMenu(menu: Menu): Boolean = false
|
|
26
|
+
fun invalidateOptionsMenu() {}
|
|
27
|
+
open fun onOptionsItemSelected(item: MenuItem): Boolean = false
|
|
28
|
+
protected open fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {}
|
|
29
|
+
open fun onBackPressed() {}
|
|
30
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Compile-time stub. See AndroidStubs.kt.
|
|
2
|
+
@file:Suppress("UNUSED_PARAMETER", "unused")
|
|
3
|
+
|
|
4
|
+
package android.content
|
|
5
|
+
|
|
6
|
+
import android.content.res.AssetManager
|
|
7
|
+
import android.content.res.Resources
|
|
8
|
+
import android.net.Uri
|
|
9
|
+
|
|
10
|
+
open class Context {
|
|
11
|
+
companion object {
|
|
12
|
+
const val INPUT_METHOD_SERVICE = "input_method"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
val assets: AssetManager = AssetManager()
|
|
16
|
+
val cacheDir: java.io.File = java.io.File(".")
|
|
17
|
+
val contentResolver: ContentResolver = ContentResolver()
|
|
18
|
+
open val resources: Resources = Resources()
|
|
19
|
+
open fun getSystemService(name: String): Any? = null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
class ContentResolver {
|
|
23
|
+
fun openInputStream(uri: Uri): java.io.InputStream? = null
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class Intent() {
|
|
27
|
+
constructor(action: String) : this()
|
|
28
|
+
|
|
29
|
+
companion object {
|
|
30
|
+
const val ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT"
|
|
31
|
+
const val ACTION_VIEW = "android.intent.action.VIEW"
|
|
32
|
+
const val CATEGORY_OPENABLE = "android.intent.category.OPENABLE"
|
|
33
|
+
const val EXTRA_MIME_TYPES = "android.intent.extra.MIME_TYPES"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
var type: String? = null
|
|
37
|
+
var data: Uri? = null
|
|
38
|
+
val action: String? = null
|
|
39
|
+
fun addCategory(category: String): Intent = this
|
|
40
|
+
fun putExtra(name: String, value: Array<String>): Intent = this
|
|
41
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Compile-time stub. See AndroidStubs.kt.
|
|
2
|
+
@file:Suppress("UNUSED_PARAMETER", "unused")
|
|
3
|
+
|
|
4
|
+
package android.content.res
|
|
5
|
+
|
|
6
|
+
class AssetManager {
|
|
7
|
+
fun open(fileName: String): java.io.InputStream = java.io.ByteArrayInputStream(ByteArray(0))
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
class Resources {
|
|
11
|
+
val displayMetrics: android.util.DisplayMetrics = android.util.DisplayMetrics()
|
|
12
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Compile-time stub. See AndroidStubs.kt.
|
|
2
|
+
//
|
|
3
|
+
// The input-method half of the platform, as far as the RealTrainer host uses
|
|
4
|
+
// it: the connection a soft keyboard commits text through, the attributes a
|
|
5
|
+
// view fills in for it, and the manager that shows and hides it.
|
|
6
|
+
@file:Suppress("UNUSED_PARAMETER", "unused")
|
|
7
|
+
|
|
8
|
+
package android.view.inputmethod
|
|
9
|
+
|
|
10
|
+
import android.os.IBinder
|
|
11
|
+
import android.view.KeyEvent
|
|
12
|
+
import android.view.View
|
|
13
|
+
|
|
14
|
+
interface InputConnection {
|
|
15
|
+
fun commitText(text: CharSequence?, newCursorPosition: Int): Boolean
|
|
16
|
+
fun deleteSurroundingText(beforeLength: Int, afterLength: Int): Boolean
|
|
17
|
+
fun setComposingText(text: CharSequence?, newCursorPosition: Int): Boolean
|
|
18
|
+
fun finishComposingText(): Boolean
|
|
19
|
+
fun sendKeyEvent(event: KeyEvent): Boolean
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
open class BaseInputConnection(targetView: View, fullEditor: Boolean) : InputConnection {
|
|
23
|
+
override fun commitText(text: CharSequence?, newCursorPosition: Int): Boolean = true
|
|
24
|
+
override fun deleteSurroundingText(beforeLength: Int, afterLength: Int): Boolean = true
|
|
25
|
+
override fun setComposingText(text: CharSequence?, newCursorPosition: Int): Boolean = true
|
|
26
|
+
override fun finishComposingText(): Boolean = true
|
|
27
|
+
override fun sendKeyEvent(event: KeyEvent): Boolean = true
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
class EditorInfo {
|
|
31
|
+
companion object {
|
|
32
|
+
const val TYPE_CLASS_TEXT = 1
|
|
33
|
+
const val TYPE_TEXT_FLAG_NO_SUGGESTIONS = 0x80000
|
|
34
|
+
const val IME_ACTION_NONE = 1
|
|
35
|
+
const val IME_FLAG_NO_EXTRACT_UI = 0x10000000
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@JvmField var inputType: Int = 0
|
|
39
|
+
@JvmField var imeOptions: Int = 0
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
class InputMethodManager {
|
|
43
|
+
fun showSoftInput(view: View, flags: Int): Boolean = true
|
|
44
|
+
fun hideSoftInputFromWindow(windowToken: IBinder?, flags: Int): Boolean = true
|
|
45
|
+
fun restartInput(view: View) {}
|
|
46
|
+
}
|