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,331 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
Import "SVGPathParser.rgr"
|
|
4
|
+
|
|
5
|
+
; ==============================================================================
|
|
6
|
+
; VectorShapes.rgr — every basic shape, expressed as a path
|
|
7
|
+
; ==============================================================================
|
|
8
|
+
; PLAN_VECTOR_IR.md Stage 3.
|
|
9
|
+
;
|
|
10
|
+
; SVG's basic shapes are not really separate primitives: `rect`, `circle`,
|
|
11
|
+
; `ellipse`, `line`, `polyline` and `polygon` each have a path equivalent that
|
|
12
|
+
; the spec states outright, and browsers render them through exactly that
|
|
13
|
+
; equivalence. Following it here means a renderer never has to grow a second
|
|
14
|
+
; way to draw a rounded corner, and a shape cannot end up looking different
|
|
15
|
+
; from the path that describes it.
|
|
16
|
+
;
|
|
17
|
+
; That matters more than it sounds, because the tree ALREADY has the beginnings
|
|
18
|
+
; of the other approach: the PDF renderer has its own drawRoundedRectPath, the
|
|
19
|
+
; raster side has fillRoundedRect and fillCircle, and each is a separate
|
|
20
|
+
; implementation of a curve that this file now derives once.
|
|
21
|
+
;
|
|
22
|
+
; Everything here is a pure function: shape parameters in, `[PathCommand]` out,
|
|
23
|
+
; no renderer, no state, no I/O. So each one can be checked against the
|
|
24
|
+
; geometry it claims to draw rather than against a rendering of it.
|
|
25
|
+
;
|
|
26
|
+
; Curves are emitted as cubics rather than arcs. A quarter ellipse is matched by
|
|
27
|
+
; a cubic to within about one part in a thousand of the radius using the
|
|
28
|
+
; standard constant below — far under a pixel at any size these are drawn — and
|
|
29
|
+
; it keeps the output free of the arc conversion every consumer would otherwise
|
|
30
|
+
; have to run.
|
|
31
|
+
; ==============================================================================
|
|
32
|
+
|
|
33
|
+
class VectorShapes {
|
|
34
|
+
|
|
35
|
+
; 4/3 * (sqrt(2) - 1). The control-point distance that makes a cubic follow
|
|
36
|
+
; a quarter circle. The same constant already appears, spelled out, in the
|
|
37
|
+
; PDF renderer's rounded-rect code.
|
|
38
|
+
sfn kappa:double () {
|
|
39
|
+
return 0.5522847498307936
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
; --------------------------------------------------------------------------
|
|
43
|
+
; Emitters
|
|
44
|
+
; --------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
sfn moveTo:PathCommand (x:double y:double) {
|
|
47
|
+
def c (new PathCommand())
|
|
48
|
+
c.type = "M"
|
|
49
|
+
c.x = x
|
|
50
|
+
c.y = y
|
|
51
|
+
return c
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
sfn lineTo:PathCommand (x:double y:double) {
|
|
55
|
+
def c (new PathCommand())
|
|
56
|
+
c.type = "L"
|
|
57
|
+
c.x = x
|
|
58
|
+
c.y = y
|
|
59
|
+
return c
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
sfn cubicTo:PathCommand (x1:double y1:double x2:double y2:double x:double y:double) {
|
|
63
|
+
def c (new PathCommand())
|
|
64
|
+
c.type = "C"
|
|
65
|
+
c.x1 = x1
|
|
66
|
+
c.y1 = y1
|
|
67
|
+
c.x2 = x2
|
|
68
|
+
c.y2 = y2
|
|
69
|
+
c.x = x
|
|
70
|
+
c.y = y
|
|
71
|
+
return c
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
sfn closePath:PathCommand () {
|
|
75
|
+
def c (new PathCommand())
|
|
76
|
+
c.type = "Z"
|
|
77
|
+
return c
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
; --------------------------------------------------------------------------
|
|
81
|
+
; line — the one shape that is never filled
|
|
82
|
+
; --------------------------------------------------------------------------
|
|
83
|
+
sfn line:[PathCommand] (x1:double y1:double x2:double y2:double) {
|
|
84
|
+
def out:[PathCommand]
|
|
85
|
+
push out (VectorShapes.moveTo(x1 y1))
|
|
86
|
+
push out (VectorShapes.lineTo(x2 y2))
|
|
87
|
+
return out
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
; --------------------------------------------------------------------------
|
|
91
|
+
; polyline / polygon — the same points, open or closed
|
|
92
|
+
; --------------------------------------------------------------------------
|
|
93
|
+
; `pts` is a flat [x0 y0 x1 y1 ...] list. A trailing odd coordinate is
|
|
94
|
+
; ignored rather than paired with a zero, because SVG says a points list
|
|
95
|
+
; with an odd count is in error and inventing the missing half would draw a
|
|
96
|
+
; line to somewhere the document never mentioned.
|
|
97
|
+
sfn polyline:[PathCommand] (pts:[double]) {
|
|
98
|
+
return (VectorShapes.pointsToPath(pts false))
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
sfn polygon:[PathCommand] (pts:[double]) {
|
|
102
|
+
return (VectorShapes.pointsToPath(pts true))
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
sfn pointsToPath:[PathCommand] (pts:[double] closed:boolean) {
|
|
106
|
+
def out:[PathCommand]
|
|
107
|
+
def n:int (idiv (array_length pts) 2)
|
|
108
|
+
if (n < 2) {
|
|
109
|
+
return out
|
|
110
|
+
}
|
|
111
|
+
push out (VectorShapes.moveTo((itemAt pts 0) (itemAt pts 1)))
|
|
112
|
+
def k:int 1
|
|
113
|
+
while (k < n) {
|
|
114
|
+
push out (VectorShapes.lineTo((itemAt pts (k * 2)) (itemAt pts ((k * 2) + 1))))
|
|
115
|
+
k = (k + 1)
|
|
116
|
+
}
|
|
117
|
+
if closed {
|
|
118
|
+
push out (VectorShapes.closePath())
|
|
119
|
+
}
|
|
120
|
+
return out
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
; --------------------------------------------------------------------------
|
|
124
|
+
; ellipse and circle
|
|
125
|
+
; --------------------------------------------------------------------------
|
|
126
|
+
; Four quarter arcs starting at the rightmost point and going in the
|
|
127
|
+
; direction of increasing y — which is downward on screen, matching the
|
|
128
|
+
; sweep the spec's own equivalent path uses.
|
|
129
|
+
;
|
|
130
|
+
; A radius of zero disables rendering per SVG 1.1, and a negative one is an
|
|
131
|
+
; error; both give no commands rather than a degenerate shape, so a caller
|
|
132
|
+
; that draws the result draws nothing instead of a stray dot.
|
|
133
|
+
sfn ellipse:[PathCommand] (cx:double cy:double rx:double ry:double) {
|
|
134
|
+
def out:[PathCommand]
|
|
135
|
+
if (rx <= 0.0) {
|
|
136
|
+
return out
|
|
137
|
+
}
|
|
138
|
+
if (ry <= 0.0) {
|
|
139
|
+
return out
|
|
140
|
+
}
|
|
141
|
+
def k:double (VectorShapes.kappa())
|
|
142
|
+
def ox:double (rx * k)
|
|
143
|
+
def oy:double (ry * k)
|
|
144
|
+
|
|
145
|
+
push out (VectorShapes.moveTo((cx + rx) cy))
|
|
146
|
+
push out (VectorShapes.cubicTo((cx + rx) (cy + oy) (cx + ox) (cy + ry) cx (cy + ry)))
|
|
147
|
+
push out (VectorShapes.cubicTo((cx - ox) (cy + ry) (cx - rx) (cy + oy) (cx - rx) cy))
|
|
148
|
+
push out (VectorShapes.cubicTo((cx - rx) (cy - oy) (cx - ox) (cy - ry) cx (cy - ry)))
|
|
149
|
+
push out (VectorShapes.cubicTo((cx + ox) (cy - ry) (cx + rx) (cy - oy) (cx + rx) cy))
|
|
150
|
+
push out (VectorShapes.closePath())
|
|
151
|
+
return out
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
sfn circle:[PathCommand] (cx:double cy:double r:double) {
|
|
155
|
+
return (VectorShapes.ellipse(cx cy r r))
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
; --------------------------------------------------------------------------
|
|
159
|
+
; rect, with or without rounded corners
|
|
160
|
+
; --------------------------------------------------------------------------
|
|
161
|
+
; SVG's rules for the corner radii, which are easy to get subtly wrong:
|
|
162
|
+
;
|
|
163
|
+
; - a negative width or height is an error, and zero disables rendering
|
|
164
|
+
; - if only one of rx/ry is given, the other takes the same value, so
|
|
165
|
+
; rx="8" alone means a circular corner and not an elliptical one
|
|
166
|
+
; - each radius is clamped to half the corresponding side, so a radius
|
|
167
|
+
; larger than the box gives a stadium rather than a self-crossing mess
|
|
168
|
+
;
|
|
169
|
+
; Pass a negative radius to mean "not specified".
|
|
170
|
+
sfn rect:[PathCommand] (x:double y:double w:double h:double rxIn:double ryIn:double) {
|
|
171
|
+
def out:[PathCommand]
|
|
172
|
+
if (w <= 0.0) {
|
|
173
|
+
return out
|
|
174
|
+
}
|
|
175
|
+
if (h <= 0.0) {
|
|
176
|
+
return out
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
def rx:double rxIn
|
|
180
|
+
def ry:double ryIn
|
|
181
|
+
; "auto": an unspecified radius follows the one that was given, and if
|
|
182
|
+
; neither was, both are zero.
|
|
183
|
+
if (rx < 0.0) {
|
|
184
|
+
rx = ry
|
|
185
|
+
}
|
|
186
|
+
if (ry < 0.0) {
|
|
187
|
+
ry = rx
|
|
188
|
+
}
|
|
189
|
+
if (rx < 0.0) {
|
|
190
|
+
rx = 0.0
|
|
191
|
+
}
|
|
192
|
+
if (ry < 0.0) {
|
|
193
|
+
ry = 0.0
|
|
194
|
+
}
|
|
195
|
+
if (rx > (w / 2.0)) {
|
|
196
|
+
rx = (w / 2.0)
|
|
197
|
+
}
|
|
198
|
+
if (ry > (h / 2.0)) {
|
|
199
|
+
ry = (h / 2.0)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
; Square corners: four lines, and no curve maths to get wrong.
|
|
203
|
+
def rounded:boolean true
|
|
204
|
+
if (rx <= 0.0) {
|
|
205
|
+
rounded = false
|
|
206
|
+
}
|
|
207
|
+
if (ry <= 0.0) {
|
|
208
|
+
rounded = false
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (rounded == false) {
|
|
212
|
+
push out (VectorShapes.moveTo(x y))
|
|
213
|
+
push out (VectorShapes.lineTo((x + w) y))
|
|
214
|
+
push out (VectorShapes.lineTo((x + w) (y + h)))
|
|
215
|
+
push out (VectorShapes.lineTo(x (y + h)))
|
|
216
|
+
push out (VectorShapes.closePath())
|
|
217
|
+
return out
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
def k:double (VectorShapes.kappa())
|
|
221
|
+
def ox:double (rx * k)
|
|
222
|
+
def oy:double (ry * k)
|
|
223
|
+
def x1:double (x + w)
|
|
224
|
+
def y1:double (y + h)
|
|
225
|
+
|
|
226
|
+
; Clockwise from the top-left corner's end, the same order the spec's
|
|
227
|
+
; equivalent path uses. Each corner's control points pull toward the
|
|
228
|
+
; corner the curve is cutting.
|
|
229
|
+
push out (VectorShapes.moveTo((x + rx) y))
|
|
230
|
+
push out (VectorShapes.lineTo((x1 - rx) y))
|
|
231
|
+
push out (VectorShapes.cubicTo((x1 - rx + ox) y x1 (y + ry - oy) x1 (y + ry)))
|
|
232
|
+
push out (VectorShapes.lineTo(x1 (y1 - ry)))
|
|
233
|
+
push out (VectorShapes.cubicTo(x1 (y1 - ry + oy) (x1 - rx + ox) y1 (x1 - rx) y1))
|
|
234
|
+
push out (VectorShapes.lineTo((x + rx) y1))
|
|
235
|
+
push out (VectorShapes.cubicTo((x + rx - ox) y1 x (y1 - ry + oy) x (y1 - ry)))
|
|
236
|
+
push out (VectorShapes.lineTo(x (y + ry)))
|
|
237
|
+
push out (VectorShapes.cubicTo(x (y + ry - oy) (x + rx - ox) y (x + rx) y))
|
|
238
|
+
push out (VectorShapes.closePath())
|
|
239
|
+
return out
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
; --------------------------------------------------------------------------
|
|
243
|
+
; Back to path data
|
|
244
|
+
; --------------------------------------------------------------------------
|
|
245
|
+
; The bridge to everything that speaks `d` rather than commands — the HTML
|
|
246
|
+
; renderer, an SVG exporter, a debug dump. Round-trips: parsing the result
|
|
247
|
+
; gives back the same geometry, which is what the test suite checks rather
|
|
248
|
+
; than comparing strings.
|
|
249
|
+
sfn asPathData:string (cmds:[PathCommand]) {
|
|
250
|
+
def out:string ""
|
|
251
|
+
def n:int (array_length cmds)
|
|
252
|
+
def k:int 0
|
|
253
|
+
while (k < n) {
|
|
254
|
+
def c:PathCommand (itemAt cmds k)
|
|
255
|
+
if (k > 0) {
|
|
256
|
+
out = (out + " ")
|
|
257
|
+
}
|
|
258
|
+
if (c.type == "M") {
|
|
259
|
+
out = (out + "M" + (VectorShapes.num(c.x)) + "," + (VectorShapes.num(c.y)))
|
|
260
|
+
}
|
|
261
|
+
if (c.type == "L") {
|
|
262
|
+
out = (out + "L" + (VectorShapes.num(c.x)) + "," + (VectorShapes.num(c.y)))
|
|
263
|
+
}
|
|
264
|
+
if (c.type == "C") {
|
|
265
|
+
out = (out + "C" + (VectorShapes.num(c.x1)) + "," + (VectorShapes.num(c.y1)))
|
|
266
|
+
out = (out + " " + (VectorShapes.num(c.x2)) + "," + (VectorShapes.num(c.y2)))
|
|
267
|
+
out = (out + " " + (VectorShapes.num(c.x)) + "," + (VectorShapes.num(c.y)))
|
|
268
|
+
}
|
|
269
|
+
if (c.type == "Q") {
|
|
270
|
+
out = (out + "Q" + (VectorShapes.num(c.x1)) + "," + (VectorShapes.num(c.y1)))
|
|
271
|
+
out = (out + " " + (VectorShapes.num(c.x)) + "," + (VectorShapes.num(c.y)))
|
|
272
|
+
}
|
|
273
|
+
if (c.type == "Z") {
|
|
274
|
+
out = (out + "Z")
|
|
275
|
+
}
|
|
276
|
+
k = (k + 1)
|
|
277
|
+
}
|
|
278
|
+
return out
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
; Rounded to four decimals, with trailing zeros and a trailing point
|
|
282
|
+
; removed. That places a point well inside a thousandth of a pixel at any
|
|
283
|
+
; size these are drawn, without carrying the noise a raw double repr brings
|
|
284
|
+
; — 0.5522847498307936 in every corner of every rounded rectangle adds up.
|
|
285
|
+
;
|
|
286
|
+
; The sign is taken off first and put back at the end. `to_int` FLOORS
|
|
287
|
+
; rather than truncating toward zero, so splitting a negative into whole
|
|
288
|
+
; and fractional parts directly gives the wrong pair: -2.5 comes apart as
|
|
289
|
+
; whole -3 and fraction 0.4999, which prints as -3.4999.
|
|
290
|
+
sfn num:string (v:double) {
|
|
291
|
+
def neg:boolean false
|
|
292
|
+
def a:double v
|
|
293
|
+
if (a < 0.0) {
|
|
294
|
+
neg = true
|
|
295
|
+
a = (0.0 - a)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
def scaled:int (to_int ((a * 10000.0) + 0.5))
|
|
299
|
+
def whole:int (idiv scaled 10000)
|
|
300
|
+
def fracPart:int (scaled - (whole * 10000))
|
|
301
|
+
|
|
302
|
+
def out:string (to_string whole)
|
|
303
|
+
if (fracPart > 0) {
|
|
304
|
+
; The trailing zeros go before the digits become text. Half a pixel
|
|
305
|
+
; is 5000 ten-thousandths, and trimming that as a STRING — pad to
|
|
306
|
+
; four, then cut one character at a time — allocated four strings
|
|
307
|
+
; to write "5". Every coordinate of every mark comes through here.
|
|
308
|
+
def digits:int 4
|
|
309
|
+
while ((fracPart - ((idiv fracPart 10) * 10)) == 0) {
|
|
310
|
+
fracPart = (idiv fracPart 10)
|
|
311
|
+
digits = (digits - 1)
|
|
312
|
+
}
|
|
313
|
+
def frac:string (to_string fracPart)
|
|
314
|
+
def pad:int (digits - (strlen frac))
|
|
315
|
+
while (pad > 0) {
|
|
316
|
+
frac = ("0" + frac)
|
|
317
|
+
pad = (pad - 1)
|
|
318
|
+
}
|
|
319
|
+
out = (out + "." + frac)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
; A value that rounds to zero has no sign to carry — "-0" would be
|
|
323
|
+
; noise in the output and is not what the number is.
|
|
324
|
+
if neg {
|
|
325
|
+
if (scaled > 0) {
|
|
326
|
+
out = ("-" + out)
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return out
|
|
330
|
+
}
|
|
331
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; ==============================================================================
|
|
4
|
+
; VectorStroke.rgr — how a stroke is drawn, independent of who draws it
|
|
5
|
+
; ==============================================================================
|
|
6
|
+
; PLAN_VECTOR_IR.md Stage 3.5.
|
|
7
|
+
;
|
|
8
|
+
; The dash pattern has to mean the same thing in all three targets: PDF has a
|
|
9
|
+
; dash operator, SVG has an attribute the browser honours, and the raster side
|
|
10
|
+
; cuts the geometry itself. Those are three different mechanisms fed by one
|
|
11
|
+
; string, so the string is parsed once, here, in the renderer-neutral module —
|
|
12
|
+
; not once per renderer, which is how the viewBox ended up meaning two
|
|
13
|
+
; different things.
|
|
14
|
+
; ==============================================================================
|
|
15
|
+
|
|
16
|
+
class VectorStroke {
|
|
17
|
+
|
|
18
|
+
; Parse a dash pattern the way SVG writes it: lengths separated by commas
|
|
19
|
+
; and/or whitespace, alternating on and off.
|
|
20
|
+
;
|
|
21
|
+
; An odd-length list repeats to become even, exactly as the spec says, so
|
|
22
|
+
; "4" means 4 on and 4 off. A negative entry invalidates the whole list per
|
|
23
|
+
; spec; an empty result therefore means "stroke solid" — which is also what
|
|
24
|
+
; a caller gets for an empty or unparseable string, so there is one thing to
|
|
25
|
+
; check rather than three.
|
|
26
|
+
sfn parseDashes:[double] (s:string) {
|
|
27
|
+
def out:[double]
|
|
28
|
+
def current:string ""
|
|
29
|
+
def i:int 0
|
|
30
|
+
def n:int (strlen s)
|
|
31
|
+
def bad:boolean false
|
|
32
|
+
while (i <= n) {
|
|
33
|
+
def isSep:boolean true
|
|
34
|
+
if (i < n) {
|
|
35
|
+
def ch:int (charAt s i)
|
|
36
|
+
isSep = false
|
|
37
|
+
if (ch == 32) { isSep = true }
|
|
38
|
+
if (ch == 9) { isSep = true }
|
|
39
|
+
if (ch == 10) { isSep = true }
|
|
40
|
+
if (ch == 13) { isSep = true }
|
|
41
|
+
if (ch == 44) { isSep = true }
|
|
42
|
+
}
|
|
43
|
+
if isSep {
|
|
44
|
+
if ((strlen current) > 0) {
|
|
45
|
+
def v@(optional):double (to_double current)
|
|
46
|
+
if v {
|
|
47
|
+
def dv:double (unwrap v)
|
|
48
|
+
if (dv < 0.0) {
|
|
49
|
+
bad = true
|
|
50
|
+
}
|
|
51
|
+
push out dv
|
|
52
|
+
} {
|
|
53
|
+
bad = true
|
|
54
|
+
}
|
|
55
|
+
current = ""
|
|
56
|
+
}
|
|
57
|
+
} {
|
|
58
|
+
current = (current + (strfromcode (charAt s i)))
|
|
59
|
+
}
|
|
60
|
+
i = (i + 1)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
def empty:[double]
|
|
64
|
+
if bad {
|
|
65
|
+
return empty
|
|
66
|
+
}
|
|
67
|
+
def cnt:int (array_length out)
|
|
68
|
+
if (cnt == 0) {
|
|
69
|
+
return empty
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
; A pattern of nothing but zeroes would never advance along the path.
|
|
73
|
+
; It is not a dash pattern, so it is not treated as one.
|
|
74
|
+
def total:double 0.0
|
|
75
|
+
def j:int 0
|
|
76
|
+
while (j < cnt) {
|
|
77
|
+
total = (total + (itemAt out j))
|
|
78
|
+
j = (j + 1)
|
|
79
|
+
}
|
|
80
|
+
if (total <= 0.0) {
|
|
81
|
+
return empty
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (((idiv cnt 2) * 2) != cnt) {
|
|
85
|
+
def k:int 0
|
|
86
|
+
while (k < cnt) {
|
|
87
|
+
push out (itemAt out k)
|
|
88
|
+
k = (k + 1)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return out
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
; Every length in a dash pattern is in user units, so it scales with the
|
|
95
|
+
; drawing exactly as the stroke width does. PDF and SVG apply the scale
|
|
96
|
+
; through their transform; the raster target has already baked the
|
|
97
|
+
; transform into its points, so it scales the pattern here instead.
|
|
98
|
+
sfn scaleDashes:[double] (dashes:[double] scale:double) {
|
|
99
|
+
def out:[double]
|
|
100
|
+
def k:int 0
|
|
101
|
+
while (k < (array_length dashes)) {
|
|
102
|
+
push out ((itemAt dashes k) * scale)
|
|
103
|
+
k = (k + 1)
|
|
104
|
+
}
|
|
105
|
+
return out
|
|
106
|
+
}
|
|
107
|
+
}
|