← Blog
0.7.0 · APPS · BROWSER · PIPELINE · PAGERENDER-PASS

Apps cc0 Pipeline Complete — HTML → CSS → Layout → Pixels (sigil-apps 3e659ad + 38bb39f)

browser pipeline css layout render milestone 0.7.0

apps/web/page_render.sg (sigil-apps 3e659ad, build fix 38bb39f) wires the complete Apps cc0 web pipeline end-to-end: DOM + CSS → style_resolverlayout_boxtext_layout (solid-fill stub) → compositor blit → pixel probes. PAGERENDER-PASS: 3 layout assertions + 3 pixel probes all pass. 17672B arm-el0. The Apps cc0 dark-lane web pipeline is now complete from raw HTML/CSS byte streams to rendered pixels. Font glyph rasterization (font_raster_str integration) is deferred to OS 0.8.


The pipeline

1. HTML tokenize
html_tokenizer.sg (de47df3) — raw HTML @ src_buf → tok_buf @0x500000
2. CSS tokenize
css_tokenizer.sg (2ae5bda) — raw CSS @ src_buf → tok_buf @0x500000 (same layout)
3. Style resolve
style_resolver.sg (6df6641) — tok_buf → StyleMap @0x700000 (48B/node: color/font_size/width/height/display/margin)
4. Layout
layout_box.sg (f33524f) — StyleMap + DOM → layout results (border-box x/y/w/h per node)
5. Text/fill
text_layout.sg (6158863) — layout results + StyleMap color → solid-fill rect per text node
6. Compositor
comp_submit_layer + comp_present — layer blit → render_buf @0x600000 → dest_buf @0x500000
7. Pixel probes
in page_render.sg — peek32 at probe coords; assert expected color

page_render.sg test — PAGERENDER-PASS

DOM + CSS setup

3 synthetic DOM nodes: h1 (tag=1), p.lead (tag=2, class="lead"), img#logo (tag=3, id="logo").
CSS rules: h1{color=0xFFFFFF white}, .lead{color=0x00DCDC cyan}, #logo{color=0xC80000 red, width=32}.

Layout results (container_w=160)

h1
x=4, y=4, w=152, h=8 — block; margin-top=4 margin-bottom=2 margin-left=4
p.lead
x=4, y=14, w=152, h=8 — block; margin-top=0 margin-bottom=4 margin-left=4
img#logo
x=4, y=28, w=32, h=32 — inline; width from StyleMap #logo width=32

Pixel probes (3 assertions)

Probe coordExpected valueColorNodeResult
(5, 6)16777215white = 0xFFFFFFinside h1 row
(5, 16)56540cyan ≈ 0x00DCDCinside p.lead row
(5, 30)13107260red ≈ 0xC80000inside img#logo

All 4 PAGERENDER-PASS assertions: layout=ok h1=ok p=ok img=ok.


What's next

page_render.sg proves the pipeline. What remains for full browser rendering:

  • Font glyph raster integration (font_raster_str → real per-character bitmaps instead of solid-fill rects): deferred to OS 0.8 font lane. The solid-fill stub is sufficient to prove layout, color, and compositor correctness.
  • style_resolver → layout_box geometry (T7): layout_box currently uses hardcoded geometry for the test; the T7 sprint wires width/height/margin from the StyleMap into layout_flow() directly.
  • Real DOM from html_tokenizer (T8): page_render.sg uses a synthetic DOM. The T8 sprint wires real HTML token stream → DOM node array → style_resolverlayout_box.
  • Scrollable pages: scroll_compositor.sg (21a7fd5) already handles viewport scroll offset — pages taller than the viewport scroll correctly once real DOM is wired.

cc0 pipeline milestone table

ModuleStatusCommit
html_tokenizer.sgde47df3
css_tokenizer.sg2ae5bda
style_resolver.sg6df6641
layout_box.sgf33524f
text_layout.sg✅ (solid-fill)6158863
scroll_compositor.sg21a7fd5
font_raster.sg✅ (boot glyphs)8f6bda0
canvas2d_fill_rectpre-existing
comp_submit_layer + comp_presentpre-existing
page_render.sg (integration)PAGERENDER-PASS3e659ad
font_raster_str (real glyphs → layout)🔲OS 0.8
Real DOM from html_tokenizer (T8)🔲next sprint