Libraries
FnLayout
experimentalA CSS visual formatting model in Elixir that turns styled documents into paginated draw commands for PDF, PNG or SVG.
What it is
FnLayout implements the CSS visual formatting model in Elixir. It takes a styled document tree, built from FnHTML and FnCSS output, and produces a flat, paint-ordered display list with every coordinate resolved. A separate renderer, FnRender, translates that display list into PDF, PNG or SVG.
It is the last Elixir stage of the Fn* document pipeline, which starts with FnXML's event streams. Together the libraries take a document and its stylesheets through to rendered pages.
Pipeline
FnHTML DOM + FnCSS Styles
-> StyledElement tree
-> Box tree (box construction)
-> Box tree with geometry (block/inline layout, floats, positioning)
-> Stacking context resolution (CSS 2.1 Appendix E paint order)
-> Pagination (geometric page breaks, y-shift per page)
-> Display List IR (flat draw commands)
-> Binary encoding -> FnRender port -> PDF/PNG/SVG
Example
Given a styled tree, layout and rendering are single calls:
# Layout with a custom viewport and real text measurement
box_tree = FnLayout.layout(styled,
width: 794.0,
height: 1123.0,
text_measure: FnLayout.TextMeasure.Port
)
# Full render pipeline: layout + display-list emission
ir_doc = FnLayout.render(styled,
width: 794.0,
page_width: 794.0,
page_height: 1123.0
)
FnLayout.layout_with_diagnostics/2 also returns paged-media diagnostics, such as content that would be clipped or hidden on the page.
Design notes
- All layout decisions are made in Elixir. The renderer is a deliberately mechanical port: it maps display-list opcodes to Cairo drawing calls and makes no layout decisions. It runs as an Erlang port, not a NIF, because those calls can block long enough to stall BEAM schedulers.
- Text measurement is pluggable. Layout asks a
TextMeasurebehaviour how wide text is. Production measures through the FnRender port; tests use a character-count stub with no external dependencies. - Paged media first. For print,
overflow: scroll | autobecomesvisible,position: fixedbecomesabsolute, andposition: stickybecomesrelative. - Explicit stages. Box construction (with anonymous box insertion), block and inline formatting contexts, margin collapsing, floats and clearance, absolute and fixed positioning, stacking contexts, pagination and binary encoding are each separate modules.
Supported properties include display (block, inline, inline-block, flex, table, none), sizing and box-sizing, margins, padding and border widths, positioning, float and clear, overflow, z-index, opacity, the font properties, line-height, text-align, white-space, vertical-align, and background and foreground color.
Conformance
FnLayout includes a visual reftest runner for the W3C web-platform-tests CSS suite. Each test is rendered to PNG through the full pipeline and compared pixel by pixel. On the print-relevant subset of 13,947 tests, the current result is:
| Status | Count | Rate |
|---|---|---|
| Pass | 5,947 | 42.6% |
| Fail | 7,358 | 52.7% |
| Clipped | 162 | 1.2% |
| Error | 480 | 3.4% |
Status
FnLayout is experimental: version 0.1, unpublished, with under half of the print-relevant reftests passing. It depends on sibling checkouts of FnHTML and FnCSS and on the FnRender binary, which needs Cairo, FreeType and HarfBuzz installed.