Node Tree — Base & Text

Every visual element in a Docraft document is a DocraftLoomNode in the loom node tree (see About Docraft). Nodes are built by DocraftLoomTreeBuilder (Craft Language Parser) from parsed Craft Language elements and then walked by the four pipeline visitors (Pipeline).

DocraftLoomNode

Base class for every node: child management, LayoutBox, positioning mode (block/absolute), z_index, optional name, padding, and CSS-like margin. Implements interfaces::DocraftLoomIVisitorNode so any node can be walked by a DocraftLoomIVisitor (see Pipeline).

class DocraftLoomNode : public docraft::loom::interfaces::DocraftLoomIVisitorNode

Represents a node in the Docraft Loom structure, supporting child-node management and layout features.

This class provides the ability to manage child nodes and store layout information through the use of LayoutBox. It also inherits from interfaces::DocraftLoomIVisitorNode, enabling visitor-based operations.

Subclassed by docraft::loom::nodes::DocraftLoomBlankLine, docraft::loom::nodes::DocraftLoomImage, docraft::loom::nodes::DocraftLoomLine, docraft::loom::nodes::DocraftLoomList, docraft::loom::nodes::DocraftLoomNewPage, docraft::loom::nodes::DocraftLoomParagraph, docraft::loom::nodes::DocraftLoomShape, docraft::loom::nodes::DocraftLoomTable, docraft::loom::nodes::DocraftLoomTableCell, docraft::loom::nodes::DocraftLoomText

Public Functions

~DocraftLoomNode() override = default
int children_count() const
void add_child(std::shared_ptr<DocraftLoomNode> child)
std::shared_ptr<DocraftLoomNode> remove_child(int index)
std::shared_ptr<const DocraftLoomNode> child(int index) const
std::shared_ptr<DocraftLoomNode> edit_child(int index)
void clear_children()
const LayoutBox &layout_box() const
LayoutBox &edit_layout_box()
DocraftPositionType position_mode() const

Returns the positioning mode (block flow or absolute).

void set_position_mode(DocraftPositionType position_mode)

Sets the positioning mode.

Absolute nodes are placed at explicit_position() during layout and do not advance the parent’s cursor.

const Position &explicit_position() const

Returns the explicit position used when position_mode() is kAbsolute.

void set_explicit_position(const Position &position)

Sets the explicit position used when position_mode() is kAbsolute.

int z_index() const

Returns the paint-order index.

Higher values paint later (on top); default 0 makes every existing node a no-op for z-index sorting.

void set_z_index(int z_index)
const std::string &name() const

Returns the node’s optional name (empty by default), settable from Craft-language’s name attribute for later lookup/debugging.

void set_name(const std::string &name)
float padding() const

Inset (in points, uniform on every side) between this node’s own box edge and where it lays out its children &#8212; e.g.

DocraftLoomRectangle offsets its children’s start position by padding() and grows its own measured size by 2x padding() around them. A no-op default for node types that don’t read it (leaves like Text/Image/Circle).

void set_padding(float padding)
const DocraftLoomMargin &margin() const

Extra space (in points, per edge) this node asks its parent’s stacking layout to reserve around it, on top of whatever gap the parent’s own spacing()/spacing-like property already adds between children (see DocraftLoomLayoutContainer::spacing()) &#8212; e.g.

a <Title> can set a larger margin() than a plain <Text>/<Paragraph> so it reads as more separated from what follows it, regardless of which container it’s stacked in. Containers combine the touching edges of two adjacent children via max(), not sum (mirrors CSS margin collapsing), so two neighbors both asking for breathing room don’t double up &#8212; vertical stacks (Rectangle/VStack) combine bottom/top, horizontal stacks (HStack) combine right/left.

void set_margin(float margin)
void set_margin(float top, float right, float bottom, float left)

LayoutBox and supporting types

LayoutBox is the per-node accumulator the pipeline fills in, one field per stage: measured_size (Measure) → frame (Layout) → page_index (Pagination). Later stages read only what earlier stages wrote — skipping a stage for a node type breaks whatever reads its field.

struct LayoutBox

Struct representing a layout box, which encapsulates layout-related data for nodes.

The LayoutBox struct is used to store the results of key steps in the layout process:

  • Measurement step (measured_size): The calculated size of the node.

  • Pagination step (page_index): The index of the page where the node is located.

  • Layout step (frame): The final position and size of the node to be applied in the layout.

Public Functions

LayoutBox() = default

Public Members

Size measured_size
int page_index
Rect frame
struct Size

Struct representing a size with width and height.

Public Members

float width
float height
struct Rect

Struct representing a rectangle with a position and size.

Public Members

Position position
Size size
struct DocraftLoomMargin

Per-edge outer spacing (points), CSS-margin-shorthand style.

Public Members

float top = 0.0F
float right = 0.0F
float bottom = 0.0F
float left = 0.0F
enum class docraft::loom::nodes::DocraftPositionType

Positioning modes for loom layout.

Values:

enumerator kBlock
enumerator kAbsolute

DocraftLoomText

The base leaf text node — <Text>. Independent bold/italic/underline/ strikeout flags, font family/size, color, alignment, and optional word wrapping (wrap_width).

class DocraftLoomText : public docraft::loom::nodes::DocraftLoomNode

Subclassed by docraft::loom::nodes::DocraftLoomPageNumber, docraft::loom::nodes::DocraftLoomSubtitle, docraft::loom::nodes::DocraftLoomTitle

Public Functions

DocraftLoomText()
DocraftLoomText(const std::string &text)
~DocraftLoomText() override = default
virtual void accept(loom::interfaces::DocraftLoomIVisitor &visitor) override
const std::string &text() const
void set_text(const std::string &text)
const std::string &font_family() const
void set_font_family(const std::string &font_family)
float font_size() const
void set_font_size(float font_size)
bool bold() const
void set_bold(bool bold)
bool italic() const
void set_italic(bool italic)
bool underline() const
void set_underline(bool underline)
bool strikeout() const
void set_strikeout(bool strikeout)
const DocraftColor &color() const
void set_color(const DocraftColor &color)
TextAlignment alignment() const
void set_alignment(TextAlignment alignment)
std::string resolved_font_name() const

Resolves the backend-registered font name for font_family() + bold() + italic() (e.g.

“Helvetica” + bold -> “Helvetica-Bold”), falling back to the plain constructed name if it isn’t registered with the backend.

float wrap_width() const

Sets the width (in points) this text wraps to.

0 (the default) disables wrapping &#8212; text() is measured/drawn as a single line, today’s behavior. Setting a positive value makes DocraftLoomMeasureProcessor word-wrap text() into wrapped_lines() at measure time, and alignment() (including kJustified) is applied per line within this width at render time.

void set_wrap_width(float wrap_width)
const std::vector<std::string> &wrapped_lines() const

The lines text() was wrapped into, populated by DocraftLoomMeasureProcessor when wrap_width() > 0.

Empty when wrapping is disabled.

void set_wrapped_lines(std::vector<std::string> lines)
float ascent() const

Distance from the baseline to the top of the line box, populated by DocraftLoomMeasureProcessor at measure time.

Rendering reads this instead of re-querying the text backend, keeping font-metric measurement confined to the measure step.

void set_ascent(float ascent)
float descent() const

Distance from the baseline to the bottom of the line box, populated by DocraftLoomMeasureProcessor at measure time.

Note

descent is negative, so the space below the baseline is stored as a negative number.

void set_descent(float descent)

DocraftLoomTitle / DocraftLoomSubtitle

Thin DocraftLoomText subclasses (<Title>/<Subtitle>) whose constructors pick larger/bolder defaults and a margin that tracks the effective font_size — all overridable via ordinary Text attributes.

class DocraftLoomTitle : public docraft::loom::nodes::DocraftLoomText

Heading-level text node (<Title> in Craft Language).

A specialized DocraftLoomText whose constructor sets h1-like defaults (larger bold font, and a larger margin() than plain text/paragraphs default to, so a title reads as more separated from what follows it) &#8212; any of these are still overridable via explicit attributes, parsed exactly like <Text>’s (see DocraftTextParser).

Public Functions

DocraftLoomTitle()
~DocraftLoomTitle() override = default
virtual void accept(loom::interfaces::DocraftLoomIVisitor &visitor) override
class DocraftLoomSubtitle : public docraft::loom::nodes::DocraftLoomText

Sub-heading text node (<Subtitle> in Craft Language).

A specialized DocraftLoomText whose constructor sets h2-like defaults (bold font, and a larger margin() than plain text/paragraphs default to &#8212; though smaller than DocraftLoomTitle’s &#8212; so it reads as separated from what follows it) &#8212; any of these are still overridable via explicit attributes, parsed exactly like <Text>’s (see DocraftTextParser).

Public Functions

DocraftLoomSubtitle()
~DocraftLoomSubtitle() override = default
virtual void accept(loom::interfaces::DocraftLoomIVisitor &visitor) override

DocraftLoomPageNumber

<PageNumber/> — a DocraftLoomText subclass that recomputes its display string from the current/total page count at render time, then delegates to the same text-rendering path as any other DocraftLoomText.

class DocraftLoomPageNumber : public docraft::loom::nodes::DocraftLoomText

Self-updating text node that displays the current page number (and total page count) at render time.

Measured using a fixed placeholder string (mirroring legacy’s DocraftPageNumber) since the real page count isn’t known until pagination completes &#8212; Measure/Layout treat it exactly like ordinary text.

Public Functions

DocraftLoomPageNumber()
~DocraftLoomPageNumber() override = default
virtual void accept(loom::interfaces::DocraftLoomIVisitor &visitor) override

DocraftLoomParagraph

<Paragraph> — groups DocraftLoomText children into one flowing vertical block with line_spacing, space_before/space_after, and a default alignment individual children can override.

class DocraftLoomParagraph : public docraft::loom::nodes::DocraftLoomNode

Loom node representing a paragraph — a block-level container of text runs.

A DocraftLoomParagraph groups one or more DocraftLoomText children into a single vertical block. During the measure pass, the paragraph accumulates the heights of its children (scaled by line_spacing) and adds space_before / space_after margins. Width is the maximum measured width among its children.

Children are added via DocraftLoomNode::add_child() and are visited recursively by the measure processor before the paragraph’s own size is computed.

Public Functions

DocraftLoomParagraph()

Constructs a paragraph with default typographic values.

Defaults: line_spacing = 1.2, space_before = 0, space_after = 0, alignment = TextAlignment::kLeft.

~DocraftLoomParagraph() override = default
virtual void accept(loom::interfaces::DocraftLoomIVisitor &visitor) override

Dispatches this node to the visitor’s visit(DocraftLoomParagraph*) overload.

Parameters:

visitor – Visitor that will process this node.

float line_spacing() const

Returns the line spacing multiplier applied to each child’s height.

A value of 1.0 means tight (no extra space between lines); 1.2 is the typographic convention for comfortable reading.

Returns:

Line spacing multiplier.

void set_line_spacing(float line_spacing)

Sets the line spacing multiplier.

Parameters:

line_spacing – Multiplier applied to each child’s height. Must be > 0.

float space_before() const

Returns the vertical space added above the paragraph (in points).

Returns:

Space before the paragraph in points.

void set_space_before(float space_before)

Sets the vertical space above the paragraph.

Parameters:

space_before – Space in points. Use 0 for no extra margin.

float space_after() const

Returns the vertical space added below the paragraph (in points).

Returns:

Space after the paragraph in points.

void set_space_after(float space_after)

Sets the vertical space below the paragraph.

Parameters:

space_after – Space in points. Use 0 for no extra margin.

TextAlignment alignment() const

Returns the default text alignment for this paragraph’s content.

Returns:

Text alignment enum value.

void set_alignment(TextAlignment alignment)

Sets the default text alignment for this paragraph’s content.

Individual DocraftLoomText children may override this with their own alignment.

Parameters:

alignment – Text alignment to apply.

DocraftLoomImage

<Image> — PNG/JPEG from a file path, or raw pixel data injected via the template engine (base64-decoded). Dimensions are never auto-derived from the file; set width/height explicitly.

class DocraftLoomImage : public docraft::loom::nodes::DocraftLoomNode

Public Functions

DocraftLoomImage() = default
~DocraftLoomImage() override = default
virtual void accept(loom::interfaces::DocraftLoomIVisitor &visitor) override
const std::string &path() const
void set_path(const std::string &path)

Sets the image path and derives format() from its file extension, mirroring legacy’s DocraftImage::set_path.

Width/height are never auto-derived from the file here (legacy’s own dimension-detection is a stub returning {0,0}).

ImageFormat format() const
const std::vector<unsigned char> &raw_data() const
int raw_pixel_width() const
int raw_pixel_height() const
bool has_raw_data() const
void set_raw_data(const std::vector<unsigned char> &data, int pixel_width, int pixel_height)
float width() const
void set_width(float width)
float height() const
void set_height(float height)

DocraftLoomBlankLine / DocraftLoomNewPage

Pure spacers/markers — <Blank/> reserves vertical space (default 12pt, about one line); <NewPage/> forces an unconditional page break during pagination. Neither one paints anything.

class DocraftLoomBlankLine : public docraft::loom::nodes::DocraftLoomNode

Public Functions

DocraftLoomBlankLine() = default
~DocraftLoomBlankLine() override = default
virtual void accept(loom::interfaces::DocraftLoomIVisitor &visitor) override
float height() const
void set_height(float height)
class DocraftLoomNewPage : public docraft::loom::nodes::DocraftLoomNode

Zero-size marker node for a forced page break.

Carries no visible content &#8212; DocraftLoomPaginationProcessor::paginate_body() recognizes it and unconditionally advances to a fresh page whenever it’s encountered among the body’s top-level children, instead of running the normal fits-on-this-page check.

Public Functions

DocraftLoomNewPage() = default
~DocraftLoomNewPage() override = default
virtual void accept(loom::interfaces::DocraftLoomIVisitor &visitor) override