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,468 @@
|
|
|
1
|
+
//! The CSS properties EVGr reads, from a declaration block
|
|
2
|
+
//! (`display:flex;width:100px`) into the fields of a node.
|
|
3
|
+
|
|
4
|
+
use ranger::prelude::*;
|
|
5
|
+
|
|
6
|
+
use crate::EvgrNode;
|
|
7
|
+
|
|
8
|
+
/// A length: `auto`, pixels, a percentage of the containing block, or a
|
|
9
|
+
/// `calc()` of the two (`v` percent plus `px` pixels).
|
|
10
|
+
#[derive(Clone, Copy)]
|
|
11
|
+
pub struct Len {
|
|
12
|
+
/// 0 auto, 1 px, 2 percent, 3 calc
|
|
13
|
+
pub kind: int,
|
|
14
|
+
pub v: double,
|
|
15
|
+
pub px: double,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
impl Len {
|
|
19
|
+
pub fn auto() -> Len {
|
|
20
|
+
Len { kind: 0, v: 0.0, px: 0.0 }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
pub fn px(v: double) -> Len {
|
|
24
|
+
Len { kind: 1, v, px: 0.0 }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/// Pixels against `base`; -1.0 when auto, or a percentage of an
|
|
28
|
+
/// indefinite base.
|
|
29
|
+
pub fn resolve(&self, base: double) -> double {
|
|
30
|
+
if self.kind == 1 {
|
|
31
|
+
return self.v;
|
|
32
|
+
}
|
|
33
|
+
if self.kind == 2 && base >= 0.0 {
|
|
34
|
+
return base * self.v / 100.0;
|
|
35
|
+
}
|
|
36
|
+
if self.kind == 3 {
|
|
37
|
+
if self.v == 0.0 {
|
|
38
|
+
return self.px;
|
|
39
|
+
}
|
|
40
|
+
if base >= 0.0 {
|
|
41
|
+
return base * self.v / 100.0 + self.px;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
-1.0
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
pub fn is_auto(&self) -> bool {
|
|
48
|
+
self.kind == 0
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// the alignment keywords, as numbers
|
|
53
|
+
pub const START: int = 0;
|
|
54
|
+
pub const END: int = 1;
|
|
55
|
+
pub const CENTER: int = 2;
|
|
56
|
+
pub const STRETCH: int = 3;
|
|
57
|
+
pub const BETWEEN: int = 4;
|
|
58
|
+
pub const AROUND: int = 5;
|
|
59
|
+
pub const EVENLY: int = 6;
|
|
60
|
+
pub const BASELINE: int = 7;
|
|
61
|
+
/// `align-self: auto` / an `align-items` left at EVG's default
|
|
62
|
+
pub const UNSET: int = -1;
|
|
63
|
+
|
|
64
|
+
pub fn parse_len(v: &str) -> Len {
|
|
65
|
+
let t = v.trim();
|
|
66
|
+
if t == "auto" || t.is_empty() {
|
|
67
|
+
return Len::auto();
|
|
68
|
+
}
|
|
69
|
+
if t.starts_with("calc(") && t.ends_with(")") {
|
|
70
|
+
return parse_calc(&t[5..t.as_bytes().len() - 1]);
|
|
71
|
+
}
|
|
72
|
+
if let Some(n) = t.strip_suffix("px") {
|
|
73
|
+
return Len::px(number(n));
|
|
74
|
+
}
|
|
75
|
+
if let Some(p) = t.strip_suffix("%") {
|
|
76
|
+
return Len { kind: 2, v: number(p), px: 0.0 };
|
|
77
|
+
}
|
|
78
|
+
Len::px(number(t))
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/// `calc(100% - 40px)`: a sum of percentages and pixels, the operators
|
|
82
|
+
/// between terms standing apart as CSS requires.
|
|
83
|
+
fn parse_calc(body: &str) -> Len {
|
|
84
|
+
let mut pct = 0.0;
|
|
85
|
+
let mut px = 0.0;
|
|
86
|
+
let mut sign = 1.0;
|
|
87
|
+
for tok in body.split_whitespace() {
|
|
88
|
+
if tok == "+" {
|
|
89
|
+
sign = 1.0;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if tok == "-" {
|
|
93
|
+
sign = -1.0;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
let l = parse_len(tok);
|
|
97
|
+
if l.kind == 2 {
|
|
98
|
+
pct += sign * l.v;
|
|
99
|
+
} else {
|
|
100
|
+
px += sign * l.resolve(0.0);
|
|
101
|
+
}
|
|
102
|
+
sign = 1.0;
|
|
103
|
+
}
|
|
104
|
+
Len { kind: 3, v: pct, px }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
pub fn number(v: &str) -> double {
|
|
108
|
+
v.trim().parse::<double>().unwrap_or(0.0)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
pub fn align_of(v: &str) -> int {
|
|
112
|
+
let t = v.trim();
|
|
113
|
+
if t == "flex-start" || t == "start" || t == "normal" || t == "left" || t == "self-start" {
|
|
114
|
+
return START;
|
|
115
|
+
}
|
|
116
|
+
if t == "flex-end" || t == "end" || t == "right" || t == "self-end" {
|
|
117
|
+
return END;
|
|
118
|
+
}
|
|
119
|
+
if t == "center" {
|
|
120
|
+
return CENTER;
|
|
121
|
+
}
|
|
122
|
+
if t == "stretch" {
|
|
123
|
+
return STRETCH;
|
|
124
|
+
}
|
|
125
|
+
if t == "space-between" {
|
|
126
|
+
return BETWEEN;
|
|
127
|
+
}
|
|
128
|
+
if t == "space-around" {
|
|
129
|
+
return AROUND;
|
|
130
|
+
}
|
|
131
|
+
if t == "space-evenly" {
|
|
132
|
+
return EVENLY;
|
|
133
|
+
}
|
|
134
|
+
if t == "baseline" {
|
|
135
|
+
return BASELINE;
|
|
136
|
+
}
|
|
137
|
+
START
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/// The values of a shorthand (`padding: 4px 8px`), as CSS spreads them over
|
|
141
|
+
/// top, right, bottom, left.
|
|
142
|
+
fn four_len(v: &str) -> Vec<Len> {
|
|
143
|
+
let parts: Vec<&str> = v.split_whitespace().collect();
|
|
144
|
+
let mut n: Vec<Len> = Vec::new();
|
|
145
|
+
for p in &parts {
|
|
146
|
+
n.push(parse_len(p));
|
|
147
|
+
}
|
|
148
|
+
let mut out: Vec<Len> = Vec::new();
|
|
149
|
+
if n.len() == 1 {
|
|
150
|
+
out.push(n[0]);
|
|
151
|
+
out.push(n[0]);
|
|
152
|
+
out.push(n[0]);
|
|
153
|
+
out.push(n[0]);
|
|
154
|
+
} else if n.len() == 2 {
|
|
155
|
+
out.push(n[0]);
|
|
156
|
+
out.push(n[1]);
|
|
157
|
+
out.push(n[0]);
|
|
158
|
+
out.push(n[1]);
|
|
159
|
+
} else if n.len() == 3 {
|
|
160
|
+
out.push(n[0]);
|
|
161
|
+
out.push(n[1]);
|
|
162
|
+
out.push(n[2]);
|
|
163
|
+
out.push(n[1]);
|
|
164
|
+
} else if n.len() >= 4 {
|
|
165
|
+
out.push(n[0]);
|
|
166
|
+
out.push(n[1]);
|
|
167
|
+
out.push(n[2]);
|
|
168
|
+
out.push(n[3]);
|
|
169
|
+
} else {
|
|
170
|
+
out.push(Len::px(0.0));
|
|
171
|
+
out.push(Len::px(0.0));
|
|
172
|
+
out.push(Len::px(0.0));
|
|
173
|
+
out.push(Len::px(0.0));
|
|
174
|
+
}
|
|
175
|
+
out
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
fn four(v: &str) -> Vec<double> {
|
|
179
|
+
let parts: Vec<&str> = v.split_whitespace().collect();
|
|
180
|
+
let mut n: Vec<double> = Vec::new();
|
|
181
|
+
for p in &parts {
|
|
182
|
+
n.push(parse_len(p).resolve(0.0).max(0.0));
|
|
183
|
+
}
|
|
184
|
+
let mut out: Vec<double> = Vec::new();
|
|
185
|
+
if n.len() == 1 {
|
|
186
|
+
out.push(n[0]);
|
|
187
|
+
out.push(n[0]);
|
|
188
|
+
out.push(n[0]);
|
|
189
|
+
out.push(n[0]);
|
|
190
|
+
} else if n.len() == 2 {
|
|
191
|
+
out.push(n[0]);
|
|
192
|
+
out.push(n[1]);
|
|
193
|
+
out.push(n[0]);
|
|
194
|
+
out.push(n[1]);
|
|
195
|
+
} else if n.len() == 3 {
|
|
196
|
+
out.push(n[0]);
|
|
197
|
+
out.push(n[1]);
|
|
198
|
+
out.push(n[2]);
|
|
199
|
+
out.push(n[1]);
|
|
200
|
+
} else if n.len() >= 4 {
|
|
201
|
+
out.push(n[0]);
|
|
202
|
+
out.push(n[1]);
|
|
203
|
+
out.push(n[2]);
|
|
204
|
+
out.push(n[3]);
|
|
205
|
+
} else {
|
|
206
|
+
out.push(0.0);
|
|
207
|
+
out.push(0.0);
|
|
208
|
+
out.push(0.0);
|
|
209
|
+
out.push(0.0);
|
|
210
|
+
}
|
|
211
|
+
out
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/// Applies one declaration; answers false for a property EVGr does not lay
|
|
215
|
+
/// out (the caller counts those).
|
|
216
|
+
pub fn apply(n: &mut EvgrNode, name: &str, value: &str) -> bool {
|
|
217
|
+
let v = value.trim();
|
|
218
|
+
if name == "display" {
|
|
219
|
+
if v == "flex" || v == "inline-flex" {
|
|
220
|
+
n.display = 1;
|
|
221
|
+
} else if v == "none" {
|
|
222
|
+
n.display = 2;
|
|
223
|
+
} else if v == "grid" || v == "inline-grid" {
|
|
224
|
+
n.display = 3;
|
|
225
|
+
} else {
|
|
226
|
+
n.display = 0;
|
|
227
|
+
}
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
if name == "flex-direction" {
|
|
231
|
+
n.row = v == "row" || v == "row-reverse";
|
|
232
|
+
n.reverse = v == "row-reverse" || v == "column-reverse";
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
if name == "flex-wrap" {
|
|
236
|
+
n.wrap = v == "wrap" || v == "wrap-reverse";
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
if name == "width" {
|
|
240
|
+
n.width = parse_len(v);
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
if name == "height" {
|
|
244
|
+
n.height = parse_len(v);
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
if name == "min-width" {
|
|
248
|
+
n.min_w = parse_len(v);
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
if name == "max-width" {
|
|
252
|
+
n.max_w = parse_len(v);
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
if name == "min-height" {
|
|
256
|
+
n.min_h = parse_len(v);
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
if name == "max-height" {
|
|
260
|
+
n.max_h = parse_len(v);
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
// padding: a percentage is of the containing block's width, so the
|
|
264
|
+
// lengths are kept and resolved when the box is laid out
|
|
265
|
+
if name == "padding" {
|
|
266
|
+
let p = four_len(v);
|
|
267
|
+
n.pad_t_len = p[0];
|
|
268
|
+
n.pad_r_len = p[1];
|
|
269
|
+
n.pad_b_len = p[2];
|
|
270
|
+
n.pad_l_len = p[3];
|
|
271
|
+
n.resolve_pads(0.0);
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
if name == "padding-top" {
|
|
275
|
+
n.pad_t_len = parse_len(v);
|
|
276
|
+
n.resolve_pads(0.0);
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
if name == "padding-right" {
|
|
280
|
+
n.pad_r_len = parse_len(v);
|
|
281
|
+
n.resolve_pads(0.0);
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
if name == "padding-bottom" {
|
|
285
|
+
n.pad_b_len = parse_len(v);
|
|
286
|
+
n.resolve_pads(0.0);
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
if name == "padding-left" {
|
|
290
|
+
n.pad_l_len = parse_len(v);
|
|
291
|
+
n.resolve_pads(0.0);
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
if name == "aspect-ratio" {
|
|
295
|
+
let parts: Vec<&str> = v.split('/').collect();
|
|
296
|
+
let a = number(parts[0]);
|
|
297
|
+
let mut b = 1.0;
|
|
298
|
+
if parts.len() >= 2 {
|
|
299
|
+
b = number(parts[1]);
|
|
300
|
+
}
|
|
301
|
+
if a > 0.0 && b > 0.0 {
|
|
302
|
+
n.ratio = a / b;
|
|
303
|
+
}
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
if name == "margin" {
|
|
307
|
+
let m = four(v);
|
|
308
|
+
n.mar_t = m[0];
|
|
309
|
+
n.mar_r = m[1];
|
|
310
|
+
n.mar_b = m[2];
|
|
311
|
+
n.mar_l = m[3];
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
if name == "margin-top" {
|
|
315
|
+
n.mar_t = parse_len(v).resolve(0.0).max(0.0);
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
if name == "margin-right" {
|
|
319
|
+
n.mar_r = parse_len(v).resolve(0.0).max(0.0);
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
322
|
+
if name == "margin-bottom" {
|
|
323
|
+
n.mar_b = parse_len(v).resolve(0.0).max(0.0);
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
if name == "margin-left" {
|
|
327
|
+
n.mar_l = parse_len(v).resolve(0.0).max(0.0);
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
if name == "gap" {
|
|
331
|
+
let parts: Vec<&str> = v.split_whitespace().collect();
|
|
332
|
+
if parts.len() >= 2 {
|
|
333
|
+
n.row_gap = parse_len(parts[0]).resolve(0.0).max(0.0);
|
|
334
|
+
n.col_gap = parse_len(parts[1]).resolve(0.0).max(0.0);
|
|
335
|
+
} else {
|
|
336
|
+
n.row_gap = parse_len(v).resolve(0.0).max(0.0);
|
|
337
|
+
n.col_gap = n.row_gap;
|
|
338
|
+
}
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
if name == "row-gap" {
|
|
342
|
+
n.row_gap = parse_len(v).resolve(0.0).max(0.0);
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
if name == "column-gap" {
|
|
346
|
+
n.col_gap = parse_len(v).resolve(0.0).max(0.0);
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
if name == "flex-grow" {
|
|
350
|
+
n.grow = number(v);
|
|
351
|
+
return true;
|
|
352
|
+
}
|
|
353
|
+
if name == "flex-shrink" {
|
|
354
|
+
n.shrink = number(v);
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
if name == "flex-basis" {
|
|
358
|
+
n.basis = parse_len(v);
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
if name == "flex" {
|
|
362
|
+
// `flex: 1` is `1 1 0`, `auto` is `1 1 auto`, `none` is `0 0 auto`
|
|
363
|
+
if v == "none" {
|
|
364
|
+
n.grow = 0.0;
|
|
365
|
+
n.shrink = 0.0;
|
|
366
|
+
n.basis = Len::auto();
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
369
|
+
if v == "auto" {
|
|
370
|
+
n.grow = 1.0;
|
|
371
|
+
n.shrink = 1.0;
|
|
372
|
+
n.basis = Len::auto();
|
|
373
|
+
return true;
|
|
374
|
+
}
|
|
375
|
+
let parts: Vec<&str> = v.split_whitespace().collect();
|
|
376
|
+
n.grow = number(parts[0]);
|
|
377
|
+
n.shrink = 1.0;
|
|
378
|
+
n.basis = Len::px(0.0);
|
|
379
|
+
if parts.len() >= 2 {
|
|
380
|
+
n.shrink = number(parts[1]);
|
|
381
|
+
}
|
|
382
|
+
if parts.len() >= 3 {
|
|
383
|
+
n.basis = parse_len(parts[2]);
|
|
384
|
+
}
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
if name == "justify-content" {
|
|
388
|
+
n.justify = align_of(v);
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
if name == "align-items" {
|
|
392
|
+
n.align_items = align_of(v);
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
if name == "align-self" {
|
|
396
|
+
if v == "auto" {
|
|
397
|
+
n.align_self = UNSET;
|
|
398
|
+
} else {
|
|
399
|
+
n.align_self = align_of(v);
|
|
400
|
+
}
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
if name == "align-content" {
|
|
404
|
+
n.align_content = align_of(v);
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
407
|
+
if name == "position" {
|
|
408
|
+
n.absolute = v == "absolute" || v == "fixed";
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
if name == "top" {
|
|
412
|
+
n.top = parse_len(v);
|
|
413
|
+
return true;
|
|
414
|
+
}
|
|
415
|
+
if name == "right" {
|
|
416
|
+
n.right = parse_len(v);
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
if name == "bottom" {
|
|
420
|
+
n.bottom = parse_len(v);
|
|
421
|
+
return true;
|
|
422
|
+
}
|
|
423
|
+
if name == "left" {
|
|
424
|
+
n.left = parse_len(v);
|
|
425
|
+
return true;
|
|
426
|
+
}
|
|
427
|
+
if name == "font-size" {
|
|
428
|
+
n.font_size = parse_len(v).resolve(0.0);
|
|
429
|
+
return true;
|
|
430
|
+
}
|
|
431
|
+
if name == "grid-template-columns" {
|
|
432
|
+
n.grid_cols = v.to_string();
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
if name == "grid-template-rows" {
|
|
436
|
+
n.grid_rows = v.to_string();
|
|
437
|
+
return true;
|
|
438
|
+
}
|
|
439
|
+
if name == "grid-template-areas" {
|
|
440
|
+
n.grid_areas = v.to_string();
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
443
|
+
if name == "grid-auto-rows" {
|
|
444
|
+
n.grid_auto_rows = v.to_string();
|
|
445
|
+
return true;
|
|
446
|
+
}
|
|
447
|
+
if name == "grid-auto-flow" {
|
|
448
|
+
n.grid_dense = v.contains("dense");
|
|
449
|
+
return true;
|
|
450
|
+
}
|
|
451
|
+
if name == "grid-column" {
|
|
452
|
+
n.grid_column = v.to_string();
|
|
453
|
+
return true;
|
|
454
|
+
}
|
|
455
|
+
if name == "grid-row" {
|
|
456
|
+
n.grid_row = v.to_string();
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
if name == "grid-area" {
|
|
460
|
+
n.grid_area = v.to_string();
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
// no effect on boxes
|
|
464
|
+
if name == "background-color" || name == "background" || name == "color" || name == "overflow" || name == "box-sizing" || name == "font-family" {
|
|
465
|
+
return true;
|
|
466
|
+
}
|
|
467
|
+
false
|
|
468
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
//! Text: EVG's default measurer (the advance table of `EVGTextMeasurer`,
|
|
2
|
+
//! line height 1.15 em) and greedy wrapping at spaces.
|
|
3
|
+
|
|
4
|
+
use ranger::prelude::*;
|
|
5
|
+
|
|
6
|
+
/// Advances of the characters 32..126 in em, as `EVGTextMeasurer.advanceEm`.
|
|
7
|
+
pub fn advance_table() -> Vec<double> {
|
|
8
|
+
vec![
|
|
9
|
+
0.27783, 0.27783, 0.35498, 0.55615, 0.55615, 0.88916, 0.66699, 0.19092,
|
|
10
|
+
0.33301, 0.33301, 0.38916, 0.58398, 0.27783, 0.33301, 0.27783, 0.27783,
|
|
11
|
+
0.55615, 0.55615, 0.55615, 0.55615, 0.55615, 0.55615, 0.55615, 0.55615,
|
|
12
|
+
0.55615, 0.55615, 0.27783, 0.27783, 0.58398, 0.58398, 0.58398, 0.55615,
|
|
13
|
+
1.01514, 0.66699, 0.66699, 0.72217, 0.72217, 0.66699, 0.61084, 0.77783,
|
|
14
|
+
0.72217, 0.27783, 0.50000, 0.66699, 0.55615, 0.83301, 0.72217, 0.77783,
|
|
15
|
+
0.66699, 0.77783, 0.72217, 0.66699, 0.61084, 0.72217, 0.66699, 0.94385,
|
|
16
|
+
0.66699, 0.66699, 0.61084, 0.27783, 0.27783, 0.27783, 0.46924, 0.55615,
|
|
17
|
+
0.33301, 0.55615, 0.55615, 0.50000, 0.55615, 0.55615, 0.27783, 0.55615,
|
|
18
|
+
0.55615, 0.22217, 0.22217, 0.50000, 0.22217, 0.83301, 0.55615, 0.55615,
|
|
19
|
+
0.55615, 0.55615, 0.33301, 0.50000, 0.27783, 0.55615, 0.50000, 0.72217,
|
|
20
|
+
0.50000, 0.50000, 0.50000, 0.33398, 0.25977, 0.33398, 0.58398,
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
pub fn line_height(font_size: double) -> double {
|
|
25
|
+
font_size * 1.15
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
pub fn measure(table: &Vec<double>, text: &str, font_size: double) -> double {
|
|
29
|
+
let mut w = 0.0;
|
|
30
|
+
for c in text.chars() {
|
|
31
|
+
let code = c as int;
|
|
32
|
+
if code >= 32 && code <= 126 {
|
|
33
|
+
w += table[(code - 32) as usize] * font_size;
|
|
34
|
+
} else {
|
|
35
|
+
w += 0.55 * font_size;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
w
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// The widest word: the narrowest the text can be.
|
|
42
|
+
pub fn min_width(table: &Vec<double>, text: &str, font_size: double) -> double {
|
|
43
|
+
let mut best = 0.0;
|
|
44
|
+
for word in text.split_whitespace() {
|
|
45
|
+
let w = measure(table, word, font_size);
|
|
46
|
+
if w > best {
|
|
47
|
+
best = w;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
best
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/// Lines of `text` broken at spaces to fit `max_w` (a word wider than that
|
|
54
|
+
/// stands on its own line): how many, and the widest.
|
|
55
|
+
pub fn wrap(table: &Vec<double>, text: &str, font_size: double, max_w: double) -> (int, double) {
|
|
56
|
+
let space = measure(table, " ", font_size);
|
|
57
|
+
let mut lines = 0;
|
|
58
|
+
let mut widest = 0.0;
|
|
59
|
+
let mut cur = -1.0;
|
|
60
|
+
for word in text.split_whitespace() {
|
|
61
|
+
let w = measure(table, word, font_size);
|
|
62
|
+
if cur < 0.0 {
|
|
63
|
+
cur = w;
|
|
64
|
+
lines += 1;
|
|
65
|
+
} else if cur + space + w <= max_w + 0.001 {
|
|
66
|
+
cur = cur + space + w;
|
|
67
|
+
} else {
|
|
68
|
+
if cur > widest {
|
|
69
|
+
widest = cur;
|
|
70
|
+
}
|
|
71
|
+
cur = w;
|
|
72
|
+
lines += 1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if cur > widest {
|
|
76
|
+
widest = cur;
|
|
77
|
+
}
|
|
78
|
+
if lines == 0 {
|
|
79
|
+
lines = 1;
|
|
80
|
+
widest = 0.0;
|
|
81
|
+
}
|
|
82
|
+
(lines, widest)
|
|
83
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; BitReader.rgr - Bit-level stream reader for JPEG decoding
|
|
4
|
+
; Handles reading individual bits and byte stuffing (FF00 → FF)
|
|
5
|
+
|
|
6
|
+
class BitReader {
|
|
7
|
+
def data:buffer (buffer_alloc 0)
|
|
8
|
+
def dataStart:int 0 ; Start position in buffer
|
|
9
|
+
def dataEnd:int 0 ; End position in buffer
|
|
10
|
+
def bytePos:int 0 ; Current byte position
|
|
11
|
+
def bitPos:int 0 ; Bits remaining in current byte (8 = full byte)
|
|
12
|
+
def currentByte:int 0 ; Current byte being read
|
|
13
|
+
def eof:boolean false
|
|
14
|
+
|
|
15
|
+
Constructor () {
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
fn init:void (buf:buffer startPos:int length:int) {
|
|
19
|
+
data = buf
|
|
20
|
+
dataStart = startPos
|
|
21
|
+
dataEnd = startPos + length
|
|
22
|
+
bytePos = startPos
|
|
23
|
+
bitPos = 0
|
|
24
|
+
currentByte = 0
|
|
25
|
+
eof = false
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fn loadNextByte:void () {
|
|
29
|
+
; Load next byte, handling FF00 byte stuffing and RST markers
|
|
30
|
+
if (bytePos >= dataEnd) {
|
|
31
|
+
eof = true
|
|
32
|
+
currentByte = 0
|
|
33
|
+
bitPos = 8
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
currentByte = (buffer_get data bytePos)
|
|
38
|
+
bytePos = bytePos + 1
|
|
39
|
+
|
|
40
|
+
; Check for byte stuffing and markers
|
|
41
|
+
if (currentByte == 255) {
|
|
42
|
+
if (bytePos < dataEnd) {
|
|
43
|
+
def nextByte:int (buffer_get data bytePos)
|
|
44
|
+
if (nextByte == 0) {
|
|
45
|
+
; FF00 = literal FF, skip the 00
|
|
46
|
+
bytePos = bytePos + 1
|
|
47
|
+
} {
|
|
48
|
+
; RST markers (D0-D7 = 208-215) - skip them
|
|
49
|
+
; These should only appear if DRI is set, but we skip them anyway
|
|
50
|
+
; as they should not affect entropy data
|
|
51
|
+
if ((nextByte >= 208) && (nextByte <= 215)) {
|
|
52
|
+
; Skip the RST marker
|
|
53
|
+
bytePos = bytePos + 1
|
|
54
|
+
; Load the next actual byte
|
|
55
|
+
this.loadNextByte()
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
; FF followed by FF is padding, skip
|
|
59
|
+
if (nextByte == 255) {
|
|
60
|
+
; FF FF padding, skip
|
|
61
|
+
bytePos = bytePos + 1
|
|
62
|
+
this.loadNextByte()
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
bitPos = 8
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fn readBit:int () {
|
|
73
|
+
; Read single bit, MSB first
|
|
74
|
+
if (bitPos == 0) {
|
|
75
|
+
this.loadNextByte()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if eof {
|
|
79
|
+
return 0
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
bitPos = bitPos - 1
|
|
83
|
+
def bit:int (bit_and (bit_shr currentByte bitPos) 1)
|
|
84
|
+
return bit
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
fn readBits:int (count:int) {
|
|
88
|
+
; Read multiple bits, MSB first
|
|
89
|
+
def result:int 0
|
|
90
|
+
def i:int 0
|
|
91
|
+
while (i < count) {
|
|
92
|
+
result = (bit_or (bit_shl result 1) (this.readBit()))
|
|
93
|
+
i = i + 1
|
|
94
|
+
}
|
|
95
|
+
return result
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
fn peekBits:int (count:int) {
|
|
99
|
+
; Peek at bits without consuming them
|
|
100
|
+
; Save state
|
|
101
|
+
def savedBytePos:int bytePos
|
|
102
|
+
def savedBitPos:int bitPos
|
|
103
|
+
def savedCurrentByte:int currentByte
|
|
104
|
+
def savedEof:boolean eof
|
|
105
|
+
|
|
106
|
+
def result:int (this.readBits(count))
|
|
107
|
+
|
|
108
|
+
; Restore state
|
|
109
|
+
bytePos = savedBytePos
|
|
110
|
+
bitPos = savedBitPos
|
|
111
|
+
currentByte = savedCurrentByte
|
|
112
|
+
eof = savedEof
|
|
113
|
+
|
|
114
|
+
return result
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fn alignToByte:void () {
|
|
118
|
+
; Skip remaining bits in current byte
|
|
119
|
+
bitPos = 0
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
fn skipRestartMarker:boolean () {
|
|
123
|
+
; Skip RST marker (FF D0-D7) after alignToByte()
|
|
124
|
+
; Returns true if marker was found and skipped, false otherwise
|
|
125
|
+
; Must be called after alignToByte() at restart interval boundaries
|
|
126
|
+
|
|
127
|
+
if (bytePos + 1 >= dataEnd) {
|
|
128
|
+
return false
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
def byte1:int (buffer_get data bytePos)
|
|
132
|
+
def byte2:int (buffer_get data (bytePos + 1))
|
|
133
|
+
|
|
134
|
+
if ((byte1 == 255) && (byte2 >= 208) && (byte2 <= 215)) {
|
|
135
|
+
; Valid RST marker found, skip it
|
|
136
|
+
bytePos = bytePos + 2
|
|
137
|
+
return true
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
; No RST marker found - this might indicate corruption or no DRI
|
|
141
|
+
return false
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
fn getBytePosition:int () {
|
|
145
|
+
return bytePos
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
fn isEOF:boolean () {
|
|
149
|
+
return eof
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
fn receiveExtend:int (length:int) {
|
|
153
|
+
; JPEG-specific: read 'length' bits and extend sign
|
|
154
|
+
; Used for DC and AC coefficient decoding
|
|
155
|
+
if (length == 0) {
|
|
156
|
+
return 0
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
def value:int (this.readBits(length))
|
|
160
|
+
|
|
161
|
+
; If MSB is 0, value is negative
|
|
162
|
+
; threshold = 2^(length-1)
|
|
163
|
+
def threshold:int (bit_shl 1 (length - 1))
|
|
164
|
+
if (value < threshold) {
|
|
165
|
+
; Negative value: subtract 2^length - 1
|
|
166
|
+
value = value - ((bit_shl threshold 1) - 1)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return value
|
|
170
|
+
}
|
|
171
|
+
}
|