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,254 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
//
|
|
4
|
+
// The same tree, laid out by EVG and by Chromium, box for box.
|
|
5
|
+
//
|
|
6
|
+
// node lib/evg/bench/layout-conformance.mjs [--json] [--only <id>] [--verbose]
|
|
7
|
+
//
|
|
8
|
+
// The cases live in `layout-cases.mjs` and are written ONCE, as CSS text. This
|
|
9
|
+
// file splits that text into `setAttribute` calls for EVG and drops it into a
|
|
10
|
+
// `style=` attribute for the browser, so neither side gets a translation the
|
|
11
|
+
// other did not.
|
|
12
|
+
//
|
|
13
|
+
// A case PASSES when every box agrees within half a pixel. Half and not zero
|
|
14
|
+
// because a browser rounds a used value into layout units and this engine does
|
|
15
|
+
// not; a real disagreement is never a rounding one.
|
|
16
|
+
//
|
|
17
|
+
// What a failure means is worth stating plainly, because this is not a test
|
|
18
|
+
// suite: it is a MEASUREMENT. Chromium is the definition of what the CSS says,
|
|
19
|
+
// so a differing box is a place where an EVG document and the CSS it was
|
|
20
|
+
// written as do not describe the same page. Some of those are known and
|
|
21
|
+
// deliberate (the initial values EVG chose differently, grouped as `defaults`),
|
|
22
|
+
// and the report separates them from the rest.
|
|
23
|
+
|
|
24
|
+
import fs from "node:fs";
|
|
25
|
+
import path from "node:path";
|
|
26
|
+
import { createRequire } from "node:module";
|
|
27
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
28
|
+
import { CASES, TEXT_CASES } from "./layout-cases.mjs";
|
|
29
|
+
|
|
30
|
+
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
|
31
|
+
const ROOT = path.resolve(HERE, "..", "..", "..");
|
|
32
|
+
const require = createRequire(import.meta.url);
|
|
33
|
+
const M = require(path.join(ROOT, "lib/evg/bin/EvgLayoutBench.cjs"));
|
|
34
|
+
|
|
35
|
+
const argv = process.argv.slice(2);
|
|
36
|
+
const AS_JSON = argv.includes("--json");
|
|
37
|
+
const VERBOSE = argv.includes("--verbose");
|
|
38
|
+
const ONLY = argv.includes("--only") ? argv[argv.indexOf("--only") + 1] : null;
|
|
39
|
+
const EPS = 0.5;
|
|
40
|
+
|
|
41
|
+
// --- the tree, numbered the same way on both sides ---------------------------
|
|
42
|
+
|
|
43
|
+
function walk(node, out) {
|
|
44
|
+
const id = "n" + out.length;
|
|
45
|
+
out.push({ id, node });
|
|
46
|
+
for (const k of node.kids || []) walk(k, out);
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// --- EVG side ----------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
function evgBuild(node) {
|
|
53
|
+
const el = new M.EVGElement();
|
|
54
|
+
for (const decl of (node.s || "").split(";")) {
|
|
55
|
+
const t = decl.trim();
|
|
56
|
+
if (!t) continue;
|
|
57
|
+
const i = t.indexOf(":");
|
|
58
|
+
if (i < 0) continue;
|
|
59
|
+
el.setAttribute(t.slice(0, i).trim(), t.slice(i + 1).trim());
|
|
60
|
+
}
|
|
61
|
+
if (node.text !== undefined) {
|
|
62
|
+
el.elementType = 1;
|
|
63
|
+
el.textContent = node.text;
|
|
64
|
+
}
|
|
65
|
+
for (const k of node.kids || []) el.addChild(evgBuild(k));
|
|
66
|
+
return el;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function evgBoxes(spec) {
|
|
70
|
+
// The reject collector is process-wide on purpose — an element has no route
|
|
71
|
+
// to the layout that will read it — so a harness that runs many documents in
|
|
72
|
+
// one process has to reset it, or case 40's complaint is still attached to
|
|
73
|
+
// case 41.
|
|
74
|
+
M.EVGReject.clearNotes();
|
|
75
|
+
const root = evgBuild(spec);
|
|
76
|
+
const lay = new M.EVGLayout();
|
|
77
|
+
lay.setPageSize(1200, 900);
|
|
78
|
+
lay.layout(root);
|
|
79
|
+
const flat = [];
|
|
80
|
+
(function collect(el) {
|
|
81
|
+
flat.push({
|
|
82
|
+
x: el.calculatedX,
|
|
83
|
+
y: el.calculatedY,
|
|
84
|
+
w: el.calculatedWidth,
|
|
85
|
+
h: el.calculatedHeight,
|
|
86
|
+
});
|
|
87
|
+
for (const k of el.children) collect(k);
|
|
88
|
+
})(root);
|
|
89
|
+
const warn = [];
|
|
90
|
+
for (let i = 0; i < lay.warningCount(); i++) warn.push(lay.warningAt(i));
|
|
91
|
+
return { flat, warn };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// --- browser side ------------------------------------------------------------
|
|
95
|
+
|
|
96
|
+
function html(spec) {
|
|
97
|
+
const render = (n) =>
|
|
98
|
+
`<div style="${(n.s || "").replace(/"/g, """)}">` +
|
|
99
|
+
(n.text !== undefined ? n.text.replace(/[<&]/g, (c) => (c === "<" ? "<" : "&")) : "") +
|
|
100
|
+
(n.kids || []).map(render).join("") +
|
|
101
|
+
`</div>`;
|
|
102
|
+
return (
|
|
103
|
+
`<!doctype html><meta charset="utf-8"><style>` +
|
|
104
|
+
`*{box-sizing:border-box;margin:0;padding:0;border:0 solid #000}` +
|
|
105
|
+
`html,body{margin:0;padding:0;font:16px/1.2 monospace}` +
|
|
106
|
+
`#host{position:absolute;left:0;top:0}` +
|
|
107
|
+
`</style><div id="host">${render(spec)}</div>`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function browserBoxes(page, spec) {
|
|
112
|
+
await page.setContent(html(spec));
|
|
113
|
+
return page.evaluate(() => {
|
|
114
|
+
const out = [];
|
|
115
|
+
const host = document.getElementById("host");
|
|
116
|
+
const origin = host.firstElementChild.getBoundingClientRect();
|
|
117
|
+
(function collect(el) {
|
|
118
|
+
const r = el.getBoundingClientRect();
|
|
119
|
+
out.push({ x: r.left - origin.left, y: r.top - origin.top, w: r.width, h: r.height });
|
|
120
|
+
for (const c of el.children) collect(c);
|
|
121
|
+
})(host.firstElementChild);
|
|
122
|
+
return out;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// --- compare -----------------------------------------------------------------
|
|
127
|
+
|
|
128
|
+
const r2 = (v) => Math.round(v * 100) / 100;
|
|
129
|
+
|
|
130
|
+
function diff(a, b) {
|
|
131
|
+
const rows = [];
|
|
132
|
+
const n = Math.max(a.length, b.length);
|
|
133
|
+
for (let i = 0; i < n; i++) {
|
|
134
|
+
const x = a[i], y = b[i];
|
|
135
|
+
if (!x || !y) {
|
|
136
|
+
rows.push({ id: "n" + i, miss: true, evg: x || null, css: y || null });
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const d = ["x", "y", "w", "h"].filter((k) => Math.abs(x[k] - y[k]) > EPS);
|
|
140
|
+
if (d.length) rows.push({ id: "n" + i, fields: d, evg: x, css: y });
|
|
141
|
+
}
|
|
142
|
+
return rows;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// --- run ---------------------------------------------------------------------
|
|
146
|
+
|
|
147
|
+
const { chromium } = require("playwright-core");
|
|
148
|
+
|
|
149
|
+
// The repo's `findChromium` names the revision playwright-core was built
|
|
150
|
+
// against, which is not always the revision that is installed. Take whatever
|
|
151
|
+
// is actually on disk, and fall back to the user's own Chrome.
|
|
152
|
+
function chromiumPath() {
|
|
153
|
+
const cache = path.join(process.env.HOME || "", "Library/Caches/ms-playwright");
|
|
154
|
+
if (!fs.existsSync(cache)) return null;
|
|
155
|
+
for (const dir of fs.readdirSync(cache).filter((d) => d.startsWith("chromium-")).sort().reverse()) {
|
|
156
|
+
for (const rel of [
|
|
157
|
+
"chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing",
|
|
158
|
+
"chrome-mac/Chromium.app/Contents/MacOS/Chromium",
|
|
159
|
+
"chrome-linux/chrome",
|
|
160
|
+
]) {
|
|
161
|
+
const p = path.join(cache, dir, rel);
|
|
162
|
+
if (fs.existsSync(p)) return p;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const exe = chromiumPath();
|
|
169
|
+
const browser = await chromium.launch(exe ? { executablePath: exe } : { channel: "chrome" });
|
|
170
|
+
const page = await browser.newPage({ viewport: { width: 1200, height: 900 } });
|
|
171
|
+
|
|
172
|
+
const results = [];
|
|
173
|
+
for (const c of CASES) {
|
|
174
|
+
if (ONLY && c.id !== ONLY) continue;
|
|
175
|
+
let evg, css, err = null;
|
|
176
|
+
let warn = [];
|
|
177
|
+
try {
|
|
178
|
+
const e = evgBoxes(c.root);
|
|
179
|
+
evg = e.flat;
|
|
180
|
+
warn = e.warn;
|
|
181
|
+
css = await browserBoxes(page, c.root);
|
|
182
|
+
} catch (ex) {
|
|
183
|
+
err = String(ex && ex.message ? ex.message : ex);
|
|
184
|
+
}
|
|
185
|
+
const rows = err ? null : diff(evg, css);
|
|
186
|
+
results.push({ ...c, root: undefined, err, rows, warn, nodes: evg ? evg.length : 0, evg, css });
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Text cases: EVG only, and behavioural.
|
|
190
|
+
const textResults = [];
|
|
191
|
+
for (const c of TEXT_CASES) {
|
|
192
|
+
if (ONLY && c.id !== ONLY) continue;
|
|
193
|
+
let ok = false, boxes = null, err = null;
|
|
194
|
+
try {
|
|
195
|
+
boxes = evgBoxes(c.root).flat;
|
|
196
|
+
ok = !!c.assert(boxes);
|
|
197
|
+
} catch (ex) {
|
|
198
|
+
err = String(ex && ex.message ? ex.message : ex);
|
|
199
|
+
}
|
|
200
|
+
textResults.push({ id: c.id, why: c.why, says: c.says, ok, err, boxes });
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
await browser.close();
|
|
204
|
+
|
|
205
|
+
if (AS_JSON) {
|
|
206
|
+
console.log(JSON.stringify({ results, textResults }, null, 2));
|
|
207
|
+
process.exit(0);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// --- report ------------------------------------------------------------------
|
|
211
|
+
|
|
212
|
+
const pad = (s, n) => String(s).padEnd(n);
|
|
213
|
+
let lastGroup = null;
|
|
214
|
+
let pass = 0, fail = 0;
|
|
215
|
+
const failing = [];
|
|
216
|
+
|
|
217
|
+
console.log("\nEVG layout vs Chromium — the same CSS, two engines\n");
|
|
218
|
+
for (const r of results) {
|
|
219
|
+
if (r.group !== lastGroup) {
|
|
220
|
+
console.log(` ── ${r.group}`);
|
|
221
|
+
lastGroup = r.group;
|
|
222
|
+
}
|
|
223
|
+
const bad = r.err || (r.rows && r.rows.length);
|
|
224
|
+
if (bad) { fail++; failing.push(r); } else pass++;
|
|
225
|
+
const mark = r.err ? "ERR " : r.rows.length ? "DIFF" : "ok ";
|
|
226
|
+
console.log(` ${mark} ${pad(r.id, 26)} ${r.nodes ? r.nodes + " boxes" : ""} ${r.rows && r.rows.length ? r.rows.length + " differ" : ""}`);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
console.log(`\n ${pass} of ${pass + fail} cases agree box for box.\n`);
|
|
230
|
+
|
|
231
|
+
if (failing.length) {
|
|
232
|
+
console.log(" Where they differ\n");
|
|
233
|
+
for (const r of failing) {
|
|
234
|
+
console.log(` ${r.id} — ${r.why}`);
|
|
235
|
+
console.log(` ${r.warn.length ? "the engine warned: " + r.warn[0] : "the engine reported nothing — the difference is silent"}`);
|
|
236
|
+
if (r.err) { console.log(` ERROR ${r.err}\n`); continue; }
|
|
237
|
+
for (const d of r.rows.slice(0, VERBOSE ? 99 : 4)) {
|
|
238
|
+
if (d.miss) { console.log(` ${d.id}: one side has no such box`); continue; }
|
|
239
|
+
const f = (o) => `x=${r2(o.x)} y=${r2(o.y)} w=${r2(o.w)} h=${r2(o.h)}`;
|
|
240
|
+
console.log(` ${d.id} [${d.fields.join(",")}]`);
|
|
241
|
+
console.log(` evg ${f(d.evg)}`);
|
|
242
|
+
console.log(` css ${f(d.css)}`);
|
|
243
|
+
}
|
|
244
|
+
if (!VERBOSE && r.rows.length > 4) console.log(` … and ${r.rows.length - 4} more`);
|
|
245
|
+
console.log("");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
console.log(" Text in layout (EVG only — see the note in the case file)\n");
|
|
250
|
+
for (const t of textResults) {
|
|
251
|
+
console.log(` ${t.err ? "ERR " : t.ok ? "ok " : "NO "} ${pad(t.id, 26)} ${t.says}`);
|
|
252
|
+
if (t.err) console.log(` ${t.err}`);
|
|
253
|
+
}
|
|
254
|
+
console.log("");
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Compiler output. Every file here is produced from a `.rgr` in lib/evg by
|
|
2
|
+
# an npm script that compiles before it runs — `evg:test`, `evg:trace:test`,
|
|
3
|
+
# `evg:compile` and the rest — so a fresh clone builds them and never needs
|
|
4
|
+
# them committed.
|
|
5
|
+
#
|
|
6
|
+
# This used to say `bin/`, which ignores a nested `bin/` directory that does
|
|
7
|
+
# not exist, so seventeen build artifacts were tracked. They were not harmless:
|
|
8
|
+
# every branch that touched EVG recompiled them, and two branches that touched
|
|
9
|
+
# EVG conflicted in a generated file neither of them had edited. The
|
|
10
|
+
# `evg_trace_cli` outputs for Python, C++ and Rust were already ignored a few
|
|
11
|
+
# lines apart in the root .gitignore — only the JavaScript one was kept, and
|
|
12
|
+
# for no reason anybody wrote down.
|
|
13
|
+
#
|
|
14
|
+
# This is the same rule gallery/ui/bin, gallery/vela/bin, gallery/book/bin and
|
|
15
|
+
# gallery/css/bin already use.
|
|
16
|
+
*
|
|
17
|
+
!.gitignore
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; evg_test.rgr - Test CLI for EVG Layout Engine
|
|
4
|
+
;
|
|
5
|
+
; Compile: npm run evg:compile
|
|
6
|
+
; Run: npm run evg:run
|
|
7
|
+
|
|
8
|
+
Import "EVGUnit.rgr"
|
|
9
|
+
Import "EVGColor.rgr"
|
|
10
|
+
Import "EVGBox.rgr"
|
|
11
|
+
Import "EVGElement.rgr"
|
|
12
|
+
Import "EVGTextMeasurer.rgr"
|
|
13
|
+
Import "EVGText.rgr"
|
|
14
|
+
Import "EVGLayout.rgr"
|
|
15
|
+
|
|
16
|
+
class EVGTest {
|
|
17
|
+
|
|
18
|
+
sfn m@(main):void () {
|
|
19
|
+
def test (new EVGTest())
|
|
20
|
+
test.run()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
fn run:void () {
|
|
24
|
+
print "=== EVG Layout Engine Tests ==="
|
|
25
|
+
print ""
|
|
26
|
+
|
|
27
|
+
this.testUnits()
|
|
28
|
+
this.testColors()
|
|
29
|
+
this.testBox()
|
|
30
|
+
this.testTextMeasurer()
|
|
31
|
+
this.testSimpleLayout()
|
|
32
|
+
this.testNestedLayout()
|
|
33
|
+
this.testAlignment()
|
|
34
|
+
|
|
35
|
+
print ""
|
|
36
|
+
print "=== All tests completed ==="
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
fn testUnits:void () {
|
|
40
|
+
print "--- Unit Parsing Tests ---"
|
|
41
|
+
|
|
42
|
+
; Test pixel parsing
|
|
43
|
+
def u1:EVGUnit (EVGUnit.parse("100px"))
|
|
44
|
+
print (" 100px -> " + (u1.toString()) + " isPixels=" + (to_string (u1.isPixels())))
|
|
45
|
+
|
|
46
|
+
; Test percentage parsing
|
|
47
|
+
def u2:EVGUnit (EVGUnit.parse("50%"))
|
|
48
|
+
print (" 50% -> " + (u2.toString()) + " isPercent=" + (to_string (u2.isPercent())))
|
|
49
|
+
|
|
50
|
+
; Test em parsing
|
|
51
|
+
def u3:EVGUnit (EVGUnit.parse("2em"))
|
|
52
|
+
print (" 2em -> " + (u3.toString()) + " isEm=" + (to_string (u3.isEm())))
|
|
53
|
+
|
|
54
|
+
; Test fill parsing
|
|
55
|
+
def u4:EVGUnit (EVGUnit.parse("fill"))
|
|
56
|
+
print (" fill -> " + (u4.toString()) + " isFill=" + (to_string (u4.isFill())))
|
|
57
|
+
|
|
58
|
+
; Test number without unit (default to px)
|
|
59
|
+
def u5:EVGUnit (EVGUnit.parse("200"))
|
|
60
|
+
print (" 200 -> " + (u5.toString()))
|
|
61
|
+
|
|
62
|
+
; Test height percentage
|
|
63
|
+
def u6:EVGUnit (EVGUnit.parse("30hp"))
|
|
64
|
+
print (" 30hp -> " + (u6.toString()) + " isHeightPercent=" + (to_string (u6.isHeightPercent())))
|
|
65
|
+
|
|
66
|
+
; Test unit resolution
|
|
67
|
+
def u7:EVGUnit (EVGUnit.parse("50%"))
|
|
68
|
+
u7.resolve(400.0 14.0)
|
|
69
|
+
print (" 50% of 400 = " + (to_string u7.pixels) + "px")
|
|
70
|
+
|
|
71
|
+
def u8:EVGUnit (EVGUnit.parse("1.5em"))
|
|
72
|
+
u8.resolve(400.0 16.0)
|
|
73
|
+
print (" 1.5em at fontSize=16 = " + (to_string u8.pixels) + "px")
|
|
74
|
+
|
|
75
|
+
print ""
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
fn testColors:void () {
|
|
79
|
+
print "--- Color Parsing Tests ---"
|
|
80
|
+
|
|
81
|
+
; Test hex colors
|
|
82
|
+
def c1:EVGColor (EVGColor.parse("#FF5733"))
|
|
83
|
+
print (" #FF5733 -> " + (c1.toCSSString()) + " hex=" + (c1.toHexString()))
|
|
84
|
+
|
|
85
|
+
; Test short hex
|
|
86
|
+
def c2:EVGColor (EVGColor.parse("#F00"))
|
|
87
|
+
print (" #F00 -> " + (c2.toCSSString()))
|
|
88
|
+
|
|
89
|
+
; Test rgb()
|
|
90
|
+
def c3:EVGColor (EVGColor.parse("rgb(100, 150, 200)"))
|
|
91
|
+
print (" rgb(100, 150, 200) -> " + (c3.toCSSString()))
|
|
92
|
+
|
|
93
|
+
; Test rgba()
|
|
94
|
+
def c4:EVGColor (EVGColor.parse("rgba(255, 0, 0, 0.5)"))
|
|
95
|
+
print (" rgba(255, 0, 0, 0.5) -> " + (c4.toCSSString()))
|
|
96
|
+
|
|
97
|
+
; Test named colors
|
|
98
|
+
def c5:EVGColor (EVGColor.parse("red"))
|
|
99
|
+
print (" red -> " + (c5.toCSSString()))
|
|
100
|
+
|
|
101
|
+
def c6:EVGColor (EVGColor.parse("blue"))
|
|
102
|
+
print (" blue -> " + (c6.toCSSString()))
|
|
103
|
+
|
|
104
|
+
; Test HSL
|
|
105
|
+
def c7:EVGColor (EVGColor.hslToRgb(195.0 100.0 50.0))
|
|
106
|
+
print (" hsl(195, 100, 50) -> " + (c7.toCSSString()))
|
|
107
|
+
|
|
108
|
+
; Test color manipulation
|
|
109
|
+
def c8:EVGColor (EVGColor.parse("#3366FF"))
|
|
110
|
+
def lighter:EVGColor (c8.lighten(0.3))
|
|
111
|
+
print (" #3366FF lighten(0.3) -> " + (lighter.toHexString()))
|
|
112
|
+
|
|
113
|
+
def darker:EVGColor (c8.darken(0.3))
|
|
114
|
+
print (" #3366FF darken(0.3) -> " + (darker.toHexString()))
|
|
115
|
+
|
|
116
|
+
print ""
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
fn testBox:void () {
|
|
120
|
+
print "--- Box Model Tests ---"
|
|
121
|
+
|
|
122
|
+
def box (new EVGBox())
|
|
123
|
+
box.setMargin((EVGUnit.px(10.0)))
|
|
124
|
+
box.setPadding((EVGUnit.px(20.0)))
|
|
125
|
+
box.borderWidth = (EVGUnit.px(2.0))
|
|
126
|
+
|
|
127
|
+
; Resolve units
|
|
128
|
+
box.resolveUnits(400.0 300.0 14.0 14.0)
|
|
129
|
+
|
|
130
|
+
print (" Box: " + (box.toString()))
|
|
131
|
+
print (" Inner width of 200: " + (to_string (box.getInnerWidth(200.0))))
|
|
132
|
+
print (" Inner height of 150: " + (to_string (box.getInnerHeight(150.0))))
|
|
133
|
+
print (" Total width from content 100: " + (to_string (box.getTotalWidth(100.0))))
|
|
134
|
+
print (" Horizontal space: " + (to_string (box.getHorizontalSpace())))
|
|
135
|
+
|
|
136
|
+
print ""
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
fn testTextMeasurer:void () {
|
|
140
|
+
print "--- Text Measurement Tests ---"
|
|
141
|
+
|
|
142
|
+
def measurer (new SimpleTextMeasurer())
|
|
143
|
+
|
|
144
|
+
; Measure simple text
|
|
145
|
+
def metrics:EVGTextMetrics (measurer.measureText("Hello, World!" "Helvetica" 14.0))
|
|
146
|
+
print (" 'Hello, World!' at 14px: " + (to_string metrics.width) + "x" + (to_string metrics.height))
|
|
147
|
+
|
|
148
|
+
; Measure with different font size
|
|
149
|
+
def metrics2:EVGTextMetrics (measurer.measureText("Hello" "Arial" 24.0))
|
|
150
|
+
print (" 'Hello' at 24px: " + (to_string metrics2.width) + "x" + (to_string metrics2.height))
|
|
151
|
+
|
|
152
|
+
; Test text wrapping
|
|
153
|
+
def longText:string "This is a long text that should wrap to multiple lines when the width is limited."
|
|
154
|
+
def lines:[string] (measurer.wrapText(longText "Helvetica" 14.0 150.0))
|
|
155
|
+
print (" Wrapped text (maxWidth=150):")
|
|
156
|
+
def i:int 0
|
|
157
|
+
while (i < (array_length lines)) {
|
|
158
|
+
def line:string (itemAt lines i)
|
|
159
|
+
print (" Line " + (to_string (i + 1)) + ": \"" + line + "\"")
|
|
160
|
+
i = i + 1
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
print ""
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
fn testSimpleLayout:void () {
|
|
167
|
+
print "--- Simple Layout Test ---"
|
|
168
|
+
|
|
169
|
+
; Create a simple layout: root with two children
|
|
170
|
+
def root (new EVGElement())
|
|
171
|
+
root.id = "root"
|
|
172
|
+
root.width = (EVGUnit.px(400.0))
|
|
173
|
+
root.height = (EVGUnit.px(300.0))
|
|
174
|
+
root.backgroundColor = (EVGColor.parse("#f0f0f0"))
|
|
175
|
+
root.box.setPadding((EVGUnit.px(20.0)))
|
|
176
|
+
|
|
177
|
+
def child1 (new EVGElement())
|
|
178
|
+
child1.id = "box1"
|
|
179
|
+
child1.width = (EVGUnit.px(100.0))
|
|
180
|
+
child1.height = (EVGUnit.px(80.0))
|
|
181
|
+
child1.backgroundColor = (EVGColor.parse("#3498db"))
|
|
182
|
+
child1.box.setMargin((EVGUnit.px(10.0)))
|
|
183
|
+
root.addChild(child1)
|
|
184
|
+
|
|
185
|
+
def child2 (new EVGElement())
|
|
186
|
+
child2.id = "box2"
|
|
187
|
+
child2.width = (EVGUnit.px(100.0))
|
|
188
|
+
child2.height = (EVGUnit.px(80.0))
|
|
189
|
+
child2.backgroundColor = (EVGColor.parse("#e74c3c"))
|
|
190
|
+
child2.box.setMargin((EVGUnit.px(10.0)))
|
|
191
|
+
root.addChild(child2)
|
|
192
|
+
|
|
193
|
+
; Layout
|
|
194
|
+
def layout (new EVGLayout())
|
|
195
|
+
layout.layout(root)
|
|
196
|
+
|
|
197
|
+
; Print results
|
|
198
|
+
print " Layout result:"
|
|
199
|
+
layout.printLayout(root 2)
|
|
200
|
+
|
|
201
|
+
print ""
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
fn testNestedLayout:void () {
|
|
205
|
+
print "--- Nested Layout Test ---"
|
|
206
|
+
|
|
207
|
+
; Create nested layout
|
|
208
|
+
def root (new EVGElement())
|
|
209
|
+
root.id = "page"
|
|
210
|
+
root.width = (EVGUnit.px(400.0))
|
|
211
|
+
root.height = (EVGUnit.px(400.0))
|
|
212
|
+
root.box.setPadding((EVGUnit.px(10.0)))
|
|
213
|
+
root.direction = "column"
|
|
214
|
+
|
|
215
|
+
; Header
|
|
216
|
+
def header (new EVGElement())
|
|
217
|
+
header.id = "header"
|
|
218
|
+
header.width = (EVGUnit.parse("100%"))
|
|
219
|
+
header.height = (EVGUnit.px(50.0))
|
|
220
|
+
header.backgroundColor = (EVGColor.parse("#2c3e50"))
|
|
221
|
+
root.addChild(header)
|
|
222
|
+
|
|
223
|
+
; Content area with two columns
|
|
224
|
+
def content (new EVGElement())
|
|
225
|
+
content.id = "content"
|
|
226
|
+
content.width = (EVGUnit.parse("100%"))
|
|
227
|
+
content.height = (EVGUnit.px(250.0))
|
|
228
|
+
content.direction = "row"
|
|
229
|
+
root.addChild(content)
|
|
230
|
+
|
|
231
|
+
def leftCol (new EVGElement())
|
|
232
|
+
leftCol.id = "sidebar"
|
|
233
|
+
leftCol.width = (EVGUnit.px(100.0))
|
|
234
|
+
leftCol.height = (EVGUnit.parse("100%"))
|
|
235
|
+
leftCol.backgroundColor = (EVGColor.parse("#34495e"))
|
|
236
|
+
content.addChild(leftCol)
|
|
237
|
+
|
|
238
|
+
def rightCol (new EVGElement())
|
|
239
|
+
rightCol.id = "main"
|
|
240
|
+
rightCol.width = (EVGUnit.px(270.0))
|
|
241
|
+
rightCol.height = (EVGUnit.parse("100%"))
|
|
242
|
+
rightCol.backgroundColor = (EVGColor.parse("#ecf0f1"))
|
|
243
|
+
rightCol.box.setPadding((EVGUnit.px(10.0)))
|
|
244
|
+
content.addChild(rightCol)
|
|
245
|
+
|
|
246
|
+
; Footer
|
|
247
|
+
def footer (new EVGElement())
|
|
248
|
+
footer.id = "footer"
|
|
249
|
+
footer.width = (EVGUnit.parse("100%"))
|
|
250
|
+
footer.height = (EVGUnit.px(40.0))
|
|
251
|
+
footer.backgroundColor = (EVGColor.parse("#2c3e50"))
|
|
252
|
+
root.addChild(footer)
|
|
253
|
+
|
|
254
|
+
; Layout
|
|
255
|
+
def layout (new EVGLayout())
|
|
256
|
+
layout.layout(root)
|
|
257
|
+
|
|
258
|
+
; Print results
|
|
259
|
+
print " Nested layout result:"
|
|
260
|
+
layout.printLayout(root 2)
|
|
261
|
+
|
|
262
|
+
print ""
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
fn testAlignment:void () {
|
|
266
|
+
print "--- Alignment Test ---"
|
|
267
|
+
|
|
268
|
+
; Test center alignment
|
|
269
|
+
def root (new EVGElement())
|
|
270
|
+
root.id = "centered"
|
|
271
|
+
root.width = (EVGUnit.px(400.0))
|
|
272
|
+
root.height = (EVGUnit.px(200.0))
|
|
273
|
+
root.align = "center"
|
|
274
|
+
root.verticalAlign = "center"
|
|
275
|
+
root.box.setPadding((EVGUnit.px(10.0)))
|
|
276
|
+
|
|
277
|
+
def box (new EVGElement())
|
|
278
|
+
box.id = "box"
|
|
279
|
+
box.width = (EVGUnit.px(100.0))
|
|
280
|
+
box.height = (EVGUnit.px(50.0))
|
|
281
|
+
box.backgroundColor = (EVGColor.parse("#9b59b6"))
|
|
282
|
+
root.addChild(box)
|
|
283
|
+
|
|
284
|
+
; Layout
|
|
285
|
+
def layout (new EVGLayout())
|
|
286
|
+
layout.layout(root)
|
|
287
|
+
|
|
288
|
+
print " Center aligned box:"
|
|
289
|
+
layout.printLayout(root 2)
|
|
290
|
+
|
|
291
|
+
; Test right alignment
|
|
292
|
+
def root2 (new EVGElement())
|
|
293
|
+
root2.id = "rightAlign"
|
|
294
|
+
root2.width = (EVGUnit.px(400.0))
|
|
295
|
+
root2.height = (EVGUnit.px(100.0))
|
|
296
|
+
root2.align = "right"
|
|
297
|
+
root2.box.setPadding((EVGUnit.px(10.0)))
|
|
298
|
+
|
|
299
|
+
def box2 (new EVGElement())
|
|
300
|
+
box2.id = "rightBox"
|
|
301
|
+
box2.width = (EVGUnit.px(80.0))
|
|
302
|
+
box2.height = (EVGUnit.px(40.0))
|
|
303
|
+
root2.addChild(box2)
|
|
304
|
+
|
|
305
|
+
def layout2 (new EVGLayout())
|
|
306
|
+
layout2.layout(root2)
|
|
307
|
+
|
|
308
|
+
print " Right aligned box:"
|
|
309
|
+
layout2.printLayout(root2 2)
|
|
310
|
+
|
|
311
|
+
print ""
|
|
312
|
+
}
|
|
313
|
+
}
|