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.
Files changed (338) hide show
  1. package/CHANGELOG.md +1160 -19
  2. package/LICENSE +3 -1
  3. package/README.md +124 -29
  4. package/dist/Lang.rgr +1188 -290
  5. package/dist/api.d.ts +2343 -879
  6. package/dist/api.js +79924 -56922
  7. package/dist/lib/JSON.rgr +102 -91
  8. package/dist/lib/Shell.rgr +4 -4
  9. package/dist/lib/apple/AppleToolchain.rgr +4 -4
  10. package/dist/lib/apple/README.md +5 -4
  11. package/dist/lib/apple/apple_test.rgr +1 -1
  12. package/dist/lib/core/README.md +1 -1
  13. package/dist/lib/evg/EVG.rgr +12 -0
  14. package/dist/lib/evg/EVGA11yFromTree.rgr +302 -0
  15. package/dist/lib/evg/EVGA11yTree.rgr +894 -0
  16. package/dist/lib/evg/EVGBox.rgr +267 -0
  17. package/dist/lib/evg/EVGBoxShorthandTest.rgr +220 -0
  18. package/dist/lib/evg/EVGCodepoint.rgr +316 -0
  19. package/dist/lib/evg/EVGColor.rgr +700 -0
  20. package/dist/lib/evg/EVGCommands.rgr +177 -0
  21. package/dist/lib/evg/EVGComponent.rgr +331 -0
  22. package/dist/lib/evg/EVGComponentTest.rgr +387 -0
  23. package/dist/lib/evg/EVGConnector.rgr +541 -0
  24. package/dist/lib/evg/EVGConnectorTest.rgr +306 -0
  25. package/dist/lib/evg/EVGDisplayList.rgr +4186 -0
  26. package/dist/lib/evg/EVGEasing.rgr +370 -0
  27. package/dist/lib/evg/EVGEffectTest.rgr +253 -0
  28. package/dist/lib/evg/EVGElement.rgr +4914 -0
  29. package/dist/lib/evg/EVGFixedTest.rgr +289 -0
  30. package/dist/lib/evg/EVGFlexRulesTest.rgr +317 -0
  31. package/dist/lib/evg/EVGFlexWrapTest.rgr +246 -0
  32. package/dist/lib/evg/EVGFling.rgr +244 -0
  33. package/dist/lib/evg/EVGFocus.rgr +400 -0
  34. package/dist/lib/evg/EVGFocusTest.rgr +399 -0
  35. package/dist/lib/evg/EVGGradient.rgr +322 -0
  36. package/dist/lib/evg/EVGGrapheme.rgr +190 -0
  37. package/dist/lib/evg/EVGGrid.rgr +975 -0
  38. package/dist/lib/evg/EVGHitTest.rgr +208 -0
  39. package/dist/lib/evg/EVGHoles.rgr +294 -0
  40. package/dist/lib/evg/EVGHostMeasurerTest.rgr +281 -0
  41. package/dist/lib/evg/EVGHostTextMeasurer.rgr +331 -0
  42. package/dist/lib/evg/EVGHostTree.rgr +834 -0
  43. package/dist/lib/evg/EVGHostTreeTest.rgr +447 -0
  44. package/dist/lib/evg/EVGImageDecode.rgr +117 -0
  45. package/dist/lib/evg/EVGImageMeasurer.rgr +86 -0
  46. package/dist/lib/evg/EVGInspect.rgr +883 -0
  47. package/dist/lib/evg/EVGInvalidateTest.rgr +432 -0
  48. package/dist/lib/evg/EVGJsonTest.rgr +535 -0
  49. package/dist/lib/evg/EVGLayout.rgr +4220 -0
  50. package/dist/lib/evg/EVGMeasure.rgr +1267 -0
  51. package/dist/lib/evg/EVGOverlayTest.rgr +626 -0
  52. package/dist/lib/evg/EVGPatch.rgr +1721 -0
  53. package/dist/lib/evg/EVGPatchTest.rgr +692 -0
  54. package/dist/lib/evg/EVGPopoverTest.rgr +395 -0
  55. package/dist/lib/evg/EVGReconcile.rgr +226 -0
  56. package/dist/lib/evg/EVGReconcileTest.rgr +421 -0
  57. package/dist/lib/evg/EVGReject.rgr +126 -0
  58. package/dist/lib/evg/EVGRelayoutTest.rgr +375 -0
  59. package/dist/lib/evg/EVGRtlLayoutTest.rgr +319 -0
  60. package/dist/lib/evg/EVGRuler.rgr +232 -0
  61. package/dist/lib/evg/EVGRulerTest.rgr +172 -0
  62. package/dist/lib/evg/EVGSelectChrome.rgr +178 -0
  63. package/dist/lib/evg/EVGStyleCacheTest.rgr +419 -0
  64. package/dist/lib/evg/EVGStyleSheet.rgr +2148 -0
  65. package/dist/lib/evg/EVGStyleStateTest.rgr +407 -0
  66. package/dist/lib/evg/EVGStyleVarTest.rgr +471 -0
  67. package/dist/lib/evg/EVGText.rgr +105 -0
  68. package/dist/lib/evg/EVGTextEngine.rgr +536 -0
  69. package/dist/lib/evg/EVGTextMeasurer.rgr +720 -0
  70. package/dist/lib/evg/EVGTimingTest.rgr +1417 -0
  71. package/dist/lib/evg/EVGToolbar.rgr +1369 -0
  72. package/dist/lib/evg/EVGTransition.rgr +728 -0
  73. package/dist/lib/evg/EVGTreeJson.rgr +721 -0
  74. package/dist/lib/evg/EVGUnit.rgr +554 -0
  75. package/dist/lib/evg/EVGViewportUnitTest.rgr +236 -0
  76. package/dist/lib/evg/EvgApp.rgr +189 -0
  77. package/dist/lib/evg/EvgBitmapTracer.rgr +4277 -0
  78. package/dist/lib/evg/EvgBitmapTracerTest.rgr +2119 -0
  79. package/dist/lib/evg/EvgHost.rgr +451 -0
  80. package/dist/lib/evg/EvgTest.rgr +91 -0
  81. package/dist/lib/evg/EvgTraceColor.rgr +236 -0
  82. package/dist/lib/evg/EvgTraceCurve.rgr +648 -0
  83. package/dist/lib/evg/EvgTraceFit.rgr +767 -0
  84. package/dist/lib/evg/EvgTracePath.rgr +435 -0
  85. package/dist/lib/evg/EvgTraceTypes.rgr +559 -0
  86. package/dist/lib/evg/EvgViewport.rgr +313 -0
  87. package/dist/lib/evg/FxDemoDoc.rgr +185 -0
  88. package/dist/lib/evg/HOSTS.md +227 -0
  89. package/dist/lib/evg/ISSUES.md +835 -0
  90. package/dist/lib/evg/PLAN_ACCESSIBILITY.md +650 -0
  91. package/dist/lib/evg/PLAN_CSS_LAYOUT_AND_FONTS.md +1124 -0
  92. package/dist/lib/evg/PLAN_EFFECTS.md +431 -0
  93. package/dist/lib/evg/PLAN_EVG.md +518 -0
  94. package/dist/lib/evg/PLAN_EVG_RENDERER.md +1674 -0
  95. package/dist/lib/evg/PLAN_INSPECTOR.md +788 -0
  96. package/dist/lib/evg/PLAN_LINKS_AND_FORMS.md +157 -0
  97. package/dist/lib/evg/PLAN_NATIVE_HOSTS.md +671 -0
  98. package/dist/lib/evg/PLAN_VECTOR_IR.md +664 -0
  99. package/dist/lib/evg/PLAN_VIEW_TRANSFORM.md +322 -0
  100. package/dist/lib/evg/PathBuilder.rgr +333 -0
  101. package/dist/lib/evg/README.md +1236 -0
  102. package/dist/lib/evg/SPEC.md +1252 -0
  103. package/dist/lib/evg/SVGPathParser.rgr +1199 -0
  104. package/dist/lib/evg/SvgParser.rgr +1736 -0
  105. package/dist/lib/evg/TODO_EVG_RENDERER.md +595 -0
  106. package/dist/lib/evg/VectorShapes.rgr +331 -0
  107. package/dist/lib/evg/VectorStroke.rgr +107 -0
  108. package/dist/lib/evg/VectorViewBox.rgr +380 -0
  109. package/dist/lib/evg/agent/README.md +290 -0
  110. package/dist/lib/evg/agent/evg_agent.rgr +899 -0
  111. package/dist/lib/evg/agent/fixtures/broken.evg.json +7 -0
  112. package/dist/lib/evg/agent/fixtures/card.evg.json +9 -0
  113. package/dist/lib/evg/agent/fixtures/connector.css +63 -0
  114. package/dist/lib/evg/agent/fixtures/connector.evg.json +14 -0
  115. package/dist/lib/evg/agent/fixtures/drawn.evg.json +129 -0
  116. package/dist/lib/evg/agent/fixtures/gradient.evg.json +4 -0
  117. package/dist/lib/evg/agent/fixtures/popover.css +99 -0
  118. package/dist/lib/evg/agent/fixtures/popover.evg.json +30 -0
  119. package/dist/lib/evg/agent/roundtrip.sh +74 -0
  120. package/dist/lib/evg/agent/smoke.sh +230 -0
  121. package/dist/lib/evg/android/README.md +97 -0
  122. package/dist/lib/evg/android/androidstubs/AndroidStubs.kt +175 -0
  123. package/dist/lib/evg/android/androidstubs/Annotation.kt +10 -0
  124. package/dist/lib/evg/android/androidstubs/App.kt +30 -0
  125. package/dist/lib/evg/android/androidstubs/Content.kt +41 -0
  126. package/dist/lib/evg/android/androidstubs/ContentRes.kt +12 -0
  127. package/dist/lib/evg/android/androidstubs/InputMethod.kt +46 -0
  128. package/dist/lib/evg/android/androidstubs/Net.kt +6 -0
  129. package/dist/lib/evg/android/androidstubs/Os.kt +30 -0
  130. package/dist/lib/evg/android/androidstubs/Util.kt +15 -0
  131. package/dist/lib/evg/android/androidstubs/View.kt +113 -0
  132. package/dist/lib/evg/android/androidstubs/Widget.kt +16 -0
  133. package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidEvgSurface.kt +323 -0
  134. package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidTextMeasurer.kt +56 -0
  135. package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/RippleEffect.kt +262 -0
  136. package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtEvgSurface.kt +238 -0
  137. package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtTextMeasurer.kt +85 -0
  138. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgEngineThread.kt +115 -0
  139. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgPainter.kt +231 -0
  140. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgSurface.kt +117 -0
  141. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/RecordingSurface.kt +94 -0
  142. package/dist/lib/evg/apple/README.md +128 -0
  143. package/dist/lib/evg/apple/Sources/CoreGraphicsEvgSurface.swift +329 -0
  144. package/dist/lib/evg/apple/Sources/CoreTextMeasurer.swift +70 -0
  145. package/dist/lib/evg/apple/Sources/EvgEngineQueue.swift +105 -0
  146. package/dist/lib/evg/apple/Sources/EvgPainter.swift +225 -0
  147. package/dist/lib/evg/apple/Sources/EvgSurface.swift +163 -0
  148. package/dist/lib/evg/apple/Sources/RecordingSurface.swift +110 -0
  149. package/dist/lib/evg/bench/EvgLayoutBench.rgr +34 -0
  150. package/dist/lib/evg/bench/README.md +64 -0
  151. package/dist/lib/evg/bench/layout-bench.mjs +316 -0
  152. package/dist/lib/evg/bench/layout-cases.mjs +510 -0
  153. package/dist/lib/evg/bench/layout-conformance.mjs +254 -0
  154. package/dist/lib/evg/bin/.gitignore +17 -0
  155. package/dist/lib/evg/evg_test.rgr +313 -0
  156. package/dist/lib/evg/gl/README.md +198 -0
  157. package/dist/lib/evg/gl/a11y-paint-check.mjs +73 -0
  158. package/dist/lib/evg/gl/blur-check.mjs +399 -0
  159. package/dist/lib/evg/gl/boxmodel.json +1 -0
  160. package/dist/lib/evg/gl/demo.html +46 -0
  161. package/dist/lib/evg/gl/effect-presets.css +285 -0
  162. package/dist/lib/evg/gl/effect-presets.js +63 -0
  163. package/dist/lib/evg/gl/effect-shots.mjs +135 -0
  164. package/dist/lib/evg/gl/evg-a11y.js +566 -0
  165. package/dist/lib/evg/gl/evg-binary.js +160 -0
  166. package/dist/lib/evg/gl/evg-engine.js +296 -0
  167. package/dist/lib/evg/gl/evg-fx.js +237 -0
  168. package/dist/lib/evg/gl/evg-gestures.js +209 -0
  169. package/dist/lib/evg/gl/evg-list.js +167 -0
  170. package/dist/lib/evg/gl/evg-measure.js +186 -0
  171. package/dist/lib/evg/gl/evg-textinput.js +303 -0
  172. package/dist/lib/evg/gl/evg-view.js +144 -0
  173. package/dist/lib/evg/gl/evg-webgl.js +3942 -0
  174. package/dist/lib/evg/gl/fx-check.mjs +998 -0
  175. package/dist/lib/evg/gl/fx-demo.html +166 -0
  176. package/dist/lib/evg/gl/fx-demo.js +2 -0
  177. package/dist/lib/evg/gl/fx-serve.mjs +47 -0
  178. package/dist/lib/evg/gl/gestures-check.mjs +189 -0
  179. package/dist/lib/evg/gl/list-binary-check.mjs +152 -0
  180. package/dist/lib/evg/gl/measure-check.mjs +135 -0
  181. package/dist/lib/evg/gl/rotation-check.mjs +207 -0
  182. package/dist/lib/evg/gl/shift-check.mjs +113 -0
  183. package/dist/lib/evg/gl/stroke-check.mjs +168 -0
  184. package/dist/lib/evg/gl/text-snap-check.mjs +139 -0
  185. package/dist/lib/evg/gl/view-check.mjs +343 -0
  186. package/dist/lib/evg/gl/view-policy-check.mjs +184 -0
  187. package/dist/lib/evg/html/evg-dom.js +318 -0
  188. package/dist/lib/evg/html/evg-html.js +600 -0
  189. package/dist/lib/evg/inspect/README.md +415 -0
  190. package/dist/lib/evg/inspect/browser-smoke.mjs +115 -0
  191. package/dist/lib/evg/inspect/evg-inspect.js +947 -0
  192. package/dist/lib/evg/inspect/shots/css.png +0 -0
  193. package/dist/lib/evg/inspect/shots/dashboard.png +0 -0
  194. package/dist/lib/evg/inspect/shots/pptx-slide.png +0 -0
  195. package/dist/lib/evg/inspect/shots/state.png +0 -0
  196. package/dist/lib/evg/inspect/shots.mjs +226 -0
  197. package/dist/lib/evg/oracle/css-blur.json +576 -0
  198. package/dist/lib/evg/oracle/css-box.json +157 -0
  199. package/dist/lib/evg/oracle/css-timing.json +709 -0
  200. package/dist/lib/evg/oracle/css_blur_oracle.mjs +529 -0
  201. package/dist/lib/evg/oracle/css_box_oracle.mjs +106 -0
  202. package/dist/lib/evg/oracle/css_timing_oracle.mjs +389 -0
  203. package/dist/lib/evg/original/EVGColor.clj +310 -0
  204. package/dist/lib/evg/original/EVGColorContext.rgr +178 -0
  205. package/dist/lib/evg/original/SVGPath.rgr +627 -0
  206. package/dist/lib/evg/original/Vec2.crgr +103 -0
  207. package/dist/lib/evg/ranger.json +9 -0
  208. package/dist/lib/evg/showcase/README.md +246 -0
  209. package/dist/lib/evg/showcase/assets/emblem.svg +30 -0
  210. package/dist/lib/evg/showcase/assets/rosette.svg +22 -0
  211. package/dist/lib/evg/showcase/build.mjs +651 -0
  212. package/dist/lib/evg/showcase/pages/album.tsx +30 -0
  213. package/dist/lib/evg/showcase/pages/boxmodel.tsx +37 -0
  214. package/dist/lib/evg/showcase/pages/cards.tsx +41 -0
  215. package/dist/lib/evg/showcase/pages/chart_api.tsx +170 -0
  216. package/dist/lib/evg/showcase/pages/charts.tsx +219 -0
  217. package/dist/lib/evg/showcase/pages/drawing.tsx +160 -0
  218. package/dist/lib/evg/showcase/pages/emoji.tsx +91 -0
  219. package/dist/lib/evg/showcase/pages/flex.tsx +46 -0
  220. package/dist/lib/evg/showcase/pages/more.tsx +332 -0
  221. package/dist/lib/evg/showcase/pages/plots.tsx +262 -0
  222. package/dist/lib/evg/showcase/pages/svg.tsx +63 -0
  223. package/dist/lib/evg/showcase/pages/tables.tsx +209 -0
  224. package/dist/lib/evg/showcase/pages/typography.tsx +43 -0
  225. package/dist/lib/evg/showcase/pages/units.tsx +35 -0
  226. package/dist/lib/evg/showcase/pages/variants.tsx +233 -0
  227. package/dist/lib/evg/showcase/pages/vector.tsx +75 -0
  228. package/dist/lib/evg/showcase/pages/views.tsx +223 -0
  229. package/dist/lib/evg/showcase/tests/chart_api_smoke.mjs +339 -0
  230. package/dist/lib/evg/showcase/tests/gl_smoke.mjs +125 -0
  231. package/dist/lib/evg/showcase/themes/chart_api-default.css +15 -0
  232. package/dist/lib/evg/showcase/themes/charts-default.css +29 -0
  233. package/dist/lib/evg/showcase/themes/drawing-default.css +35 -0
  234. package/dist/lib/evg/showcase/themes/more-default.css +128 -0
  235. package/dist/lib/evg/showcase/themes/plots-default.css +18 -0
  236. package/dist/lib/evg/showcase/themes/showcase.css +508 -0
  237. package/dist/lib/evg/showcase/themes/tables-default.css +123 -0
  238. package/dist/lib/evg/showcase/themes/variants-default.css +15 -0
  239. package/dist/lib/evg/showcase/themes/views-default.css +15 -0
  240. package/dist/lib/evg/tools/bench_vs_potrace.mjs +290 -0
  241. package/dist/lib/evg/tools/evg_image_tool.rgr +488 -0
  242. package/dist/lib/evg/tools/evg_trace_bench.rgr +114 -0
  243. package/dist/lib/evg/tools/evg_trace_cli.rgr +662 -0
  244. package/dist/lib/evg/tools/evg_trace_cpp_bench.rgr +83 -0
  245. package/dist/lib/evg/tools/run_trace_bench.sh +74 -0
  246. package/dist/lib/evg/tools/run_trace_cli_smoke.sh +128 -0
  247. package/dist/lib/evg/web/responsive/EvgResponsiveCheck.rgr +271 -0
  248. package/dist/lib/evg/web/responsive/EvgResponsiveDemo.rgr +531 -0
  249. package/dist/lib/evg/web/responsive/README.md +97 -0
  250. package/dist/lib/evg/web/responsive/build.mjs +90 -0
  251. package/dist/lib/evg/web/responsive/dom-check.mjs +169 -0
  252. package/dist/lib/evg/web/responsive/index.html +177 -0
  253. package/dist/lib/evg/web/responsive/smoke.mjs +221 -0
  254. package/dist/lib/evg/web/tools/assets-client.mjs +95 -0
  255. package/dist/lib/evg/web/tools/boot-bench.mjs +189 -0
  256. package/dist/lib/evg/web/tools/inline-assets.mjs +119 -0
  257. package/dist/lib/evg/web/tools/minify.mjs +60 -0
  258. package/dist/lib/evg/web/tracer/build.mjs +87 -0
  259. package/dist/lib/evg/web/tracer/index.html +2805 -0
  260. package/dist/lib/evg/web/tracer/sample.png +0 -0
  261. package/dist/lib/evg/web/tracer/smoke.mjs +1162 -0
  262. package/dist/lib/evgr/Cargo.lock +21 -0
  263. package/dist/lib/evgr/Cargo.toml +19 -0
  264. package/dist/lib/evgr/README.md +140 -0
  265. package/dist/lib/evgr/bench/NativeBench.rgr +246 -0
  266. package/dist/lib/evgr/bench/compare.mjs +252 -0
  267. package/dist/lib/evgr/bench/speed.mjs +277 -0
  268. package/dist/lib/evgr/bin/.gitignore +3 -0
  269. package/dist/lib/evgr/src/bin/bench.rs +106 -0
  270. package/dist/lib/evgr/src/bin/smoke.rs +13 -0
  271. package/dist/lib/evgr/src/grid.rs +730 -0
  272. package/dist/lib/evgr/src/lib.rs +1003 -0
  273. package/dist/lib/evgr/src/style.rs +468 -0
  274. package/dist/lib/evgr/src/text.rs +83 -0
  275. package/dist/lib/image/BitReader.rgr +171 -0
  276. package/dist/lib/image/Buffer.rgr +173 -0
  277. package/dist/lib/image/DCT.rgr +283 -0
  278. package/dist/lib/image/Deflate.rgr +339 -0
  279. package/dist/lib/image/HuffmanDecoder.rgr +181 -0
  280. package/dist/lib/image/ImageBuffer.rgr +706 -0
  281. package/dist/lib/image/JPEGDecoder.rgr +808 -0
  282. package/dist/lib/image/PNGDecoder.rgr +544 -0
  283. package/dist/lib/image/PNGEncoder.rgr +388 -0
  284. package/dist/lib/image/PPMImage.rgr +224 -0
  285. package/dist/lib/image/ProgressiveJPEGDecoder.rgr +1154 -0
  286. package/dist/lib/image/README.md +33 -0
  287. package/dist/lib/image/RasterBuffer.rgr +294 -0
  288. package/dist/lib/image/VP8BoolDecoder.rgr +163 -0
  289. package/dist/lib/image/WebPDecoder.rgr +433 -0
  290. package/dist/lib/image/WebPLossless.rgr +1035 -0
  291. package/dist/lib/image/WebPLossy.rgr +1929 -0
  292. package/dist/lib/image/ranger.json +9 -0
  293. package/dist/lib/image/testdata/webp/anim_2f_24x16.webp +0 -0
  294. package/dist/lib/image/testdata/webp/fixtures.txt +33 -0
  295. package/dist/lib/image/testdata/webp/gen_fixtures.py +261 -0
  296. package/dist/lib/image/testdata/webp/ll_1x1.webp +0 -0
  297. package/dist/lib/image/testdata/webp/ll_alpha_29x21.webp +0 -0
  298. package/dist/lib/image/testdata/webp/ll_gradient_64x64.webp +0 -0
  299. package/dist/lib/image/testdata/webp/ll_meta_32x32.webp +0 -0
  300. package/dist/lib/image/testdata/webp/ll_noise_17x9.webp +0 -0
  301. package/dist/lib/image/testdata/webp/ll_pal11_23x11.webp +0 -0
  302. package/dist/lib/image/testdata/webp/ll_pal2_19x7.webp +0 -0
  303. package/dist/lib/image/testdata/webp/ll_pal40_16x16.webp +0 -0
  304. package/dist/lib/image/testdata/webp/ll_pal4_13x5.webp +0 -0
  305. package/dist/lib/image/testdata/webp/ll_photo_40x30.webp +0 -0
  306. package/dist/lib/image/testdata/webp/ll_predictors_64x32.webp +0 -0
  307. package/dist/lib/image/testdata/webp/ly_1x1.webp +0 -0
  308. package/dist/lib/image/testdata/webp/ly_alph_raw_f0_21x13.webp +0 -0
  309. package/dist/lib/image/testdata/webp/ly_alph_raw_f1_21x13.webp +0 -0
  310. package/dist/lib/image/testdata/webp/ly_alph_raw_f2_21x13.webp +0 -0
  311. package/dist/lib/image/testdata/webp/ly_alph_raw_f3_21x13.webp +0 -0
  312. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f0_21x13.webp +0 -0
  313. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f1_21x13.webp +0 -0
  314. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f2_21x13.webp +0 -0
  315. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f3_21x13.webp +0 -0
  316. package/dist/lib/image/testdata/webp/ly_alpha_33x17.webp +0 -0
  317. package/dist/lib/image/testdata/webp/ly_exif_15x11.webp +0 -0
  318. package/dist/lib/image/testdata/webp/ly_i16_96x80.webp +0 -0
  319. package/dist/lib/image/testdata/webp/ly_nofilter_24x20.webp +0 -0
  320. package/dist/lib/image/testdata/webp/ly_odd_17x9.webp +0 -0
  321. package/dist/lib/image/testdata/webp/ly_photo_48x40.webp +0 -0
  322. package/dist/lib/image/testdata/webp/ly_q100_20x18.webp +0 -0
  323. package/dist/lib/image/testdata/webp/ly_sharp_40x36.webp +0 -0
  324. package/dist/lib/image/testdata/webp/ly_simple_filter_33x31.webp +0 -0
  325. package/dist/lib/image/testdata/webp/ly_vpx_parts8_37x45.webp +0 -0
  326. package/dist/lib/image/testdata/webp/ly_vpx_skip_96x80.webp +0 -0
  327. package/dist/lib/image/tests/WebPDecodeTool.rgr +81 -0
  328. package/dist/lib/image/tests/WebPDecoderTest.rgr +1162 -0
  329. package/dist/lib/image/tests/run_webp_tests.sh +39 -0
  330. package/dist/lib/rust/RsJson.rgr +468 -0
  331. package/dist/lib/rust/RsPrelude.rgr +1663 -0
  332. package/dist/lib/shell_test.rgr +7 -7
  333. package/dist/lib/stdlib.rgr +21 -5
  334. package/dist/lib/zip/ranger.json +6 -0
  335. package/dist/rgrc.js +87318 -67610
  336. package/package.json +1010 -1040
  337. package/dist/README.md +0 -117
  338. 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, "&quot;")}">` +
99
+ (n.text !== undefined ? n.text.replace(/[<&]/g, (c) => (c === "<" ? "&lt;" : "&amp;")) : "") +
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
+ }