(** Smoke test: parse SX, render to node tree, measure, layout, paint to PNG. *) open Sx_native.Sx_native_types let demo_sx = {| (div :class "flex flex-col items-center gap-6 p-8 bg-stone-50" (h1 :class "text-3xl font-bold text-stone-800" "SX Native Browser") (p :class "text-stone-500" "Rendering s-expressions directly to pixels") (div :class "flex gap-4 items-center" (div :class "p-4 rounded-lg bg-white border border-stone-200 shadow" (h3 :class "font-bold text-stone-700" "No HTML") (p :class "text-sm text-stone-500" "This is not a web page")) (div :class "p-4 rounded-lg bg-white border border-stone-200 shadow" (h3 :class "font-bold text-stone-700" "No CSS") (p :class "text-sm text-stone-500" "Tailwind classes parsed to native styles")) (div :class "p-4 rounded-lg bg-white border border-stone-200 shadow" (h3 :class "font-bold text-stone-700" "No JavaScript") (p :class "text-sm text-stone-500" "The SX evaluator does everything"))) (div :class "p-6 rounded-lg bg-violet-600" (p :class "text-white text-lg font-bold" "5000 lines of OCaml instead of 35 million lines of browser engine"))) |} let rec count_nodes (node : node) : int = 1 + List.fold_left (fun acc c -> acc + count_nodes c) 0 node.children let rec print_tree indent (node : node) = let prefix = String.make (indent * 2) ' ' in let text_info = match node.text with | Some t -> Printf.sprintf " \"%s\"" (if String.length t > 30 then String.sub t 0 30 ^ "..." else t) | None -> "" in let size_info = Printf.sprintf " [%.0fx%.0f @ (%.0f,%.0f)]" node.box.w node.box.h node.box.x node.box.y in Printf.printf "%s<%s>%s%s\n" prefix node.tag text_info size_info; List.iter (print_tree (indent + 1)) node.children let () = Printf.printf "=== SX Native Browser Smoke Test ===\n\n"; (* 1. Parse *) let values = Sx_parser.parse_all demo_sx in Printf.printf "1. Parsed %d top-level form(s)\n" (List.length values); (* 2. Render to node tree *) let root = Sx_native.Sx_native_render.render_page values in let n = count_nodes root in Printf.printf "2. Render tree: %d nodes, root tag=%s\n" n root.tag; (* 3. Create Cairo surface for measurement *) let surface = Cairo.Image.create Cairo.Image.ARGB32 ~w:1024 ~h:768 in let cr = Cairo.create surface in (* 4. Measure *) Sx_native.Sx_native_layout.measure cr root; Printf.printf "3. Measured intrinsic size: %.0f x %.0f\n" root.box.w root.box.h; (* 5. Layout *) Sx_native.Sx_native_layout.layout root 0. 0. 1024. 732.; Printf.printf "4. Layout complete, root positioned at (%.0f, %.0f) size %.0f x %.0f\n" root.box.x root.box.y root.box.w root.box.h; (* 6. Paint *) Sx_native.Sx_native_paint.paint_scene cr root "sx://demo" 1024. 768.; Cairo.Surface.flush surface; (* 7. Write PNG *) let png_path = "/tmp/sx_browser_test.png" in Cairo.PNG.write surface png_path; Printf.printf "5. Rendered to %s\n\n" png_path; (* Print tree *) Printf.printf "=== Render Tree ===\n"; print_tree 0 root; Cairo.Surface.finish surface; Printf.printf "\n=== All OK! ===\n"