pub fn render_static<'a>(
arena: &'a Arena,
root_id: u32,
width: u16,
transform_of: &'a TransformAccessor<'a>,
color_level: ColorLevel,
) -> StringExpand description
Render the static subtree (ink’s <Static>) to its standalone output
string — the text ink prints once, above the live region.
This is the SECOND render pass, a faithful port of renderer.ts’s static
branch (renderer.ts:46-66):
let staticOutput;
if (node.staticNode?.yogaNode) {
staticOutput = new Output({
width: node.staticNode.yogaNode.getComputedWidth(),
height: node.staticNode.yogaNode.getComputedHeight(),
});
renderNodeToOutput(node.staticNode, staticOutput, {skipStaticElements: false});
}
// …
staticOutput: staticOutput ? `${staticOutput.get().output}\n` : '',Semantics, point by point:
- Find the static node. ink tracks a single
node.staticNodeset by the reconciler wheninternal_staticis applied (reconciler.ts:236-244). The arena instead marks the node withis_static(set byOp::SetStatic), so we DFS fromroot_idfor the firstis_staticnode. No static node → return""(the common case; matchesstaticNodebeingundefined). - Layout. Reuse
build_layout_engineat the SAMEwidthink lays the root out at — the static node is part of that one tree, so its computed rect (engine.computed(static_id)) falls out of the single root layout, exactly asnode.staticNode.yogaNodeis laid out by the root’scalculateLayout. If the static id has no computed rect, return""(matchesnode.staticNode?.yogaNodebeing absent). - Own-sized grid. Size the static grid to the static node’s OWN computed
width/height (renderer.ts:50-52:
new Output({width: …getComputedWidth(), height: …getComputedHeight()})), NOT the root’s. - Walk at offset 0 via
walk_static(skipStaticElements: false): the static entry’s own computed left/top become the first write position (render-node-to-output.ts:129-130 with offsetX/Y defaulting to 0). - Trailing newline (renderer.ts:64-66): a PRESENT static node always
appends
\n(“static output doesn’t have one, so interactive output will override last line of static output”), even for an empty body (→"\n"). An ABSENT static node yields"". A zero-dimensioned static node skipsGrid::newand still yields"\n", matchingstaticOutput.get().outputbeing""for an emptyOutputplus the appended newline.
transform_of is the same per-node own-transform seam render_styled uses;
the napi caller passes the SAME accessor so a <Transform>/<Text color>
inside <Static> is honored in the static pass too.