Flow Content

The PDF flow-content implementation is split into four peer families: block, inline, list-bullet, and text. Each family has source-defined decoration, reflow, positioning, and/or rendering responsibilities under pdf/src. This page excludes SVG text, diagnostic text, table layout, and broader pipeline orchestration.

[!WARNING] The inspected files establish source-defined methods and direct call relationships, but do not establish application-level renderer dispatch, runtime reachability, or a successful PDF execution. List-bullet vertical placement is explicitly approximate in the source and may produce imperfect marker alignment.

Locate the implementations

Family Decorator Reflower Positioner Renderer
Block pdf/src/FrameDecorator/Block.php pdf/src/FrameReflower/Block.php pdf/src/Positioner/Block.php pdf/src/Renderer/Block.php
Inline pdf/src/FrameDecorator/Inline.php pdf/src/FrameReflower/Inline.php pdf/src/Positioner/Inline.php pdf/src/Renderer/Inline.php
List bullet pdf/src/FrameDecorator/ListBullet.php pdf/src/FrameReflower/ListBullet.php pdf/src/Positioner/ListBullet.php pdf/src/Renderer/ListBullet.php
Text pdf/src/FrameDecorator/Text.php pdf/src/FrameReflower/Text.php — pdf/src/Renderer/Text.php

Source-defined flow

flowchart TD
    b1["Block reflow"]
    b2["Block positioning"]
    b3["Child reflow"]
    i1["Inline reflow"]
    i2["Inline positioning"]
    i3["Block line-box insertion"]
    t1["Text line layout"]
    t2["Text reflow"]
    l1["List-bullet reflow"]
    l2["List-bullet positioning"]

    b1 --> b2
    b1 --> b3
    i1 --> i2
    i1 --> i3
    t2 --> t1
    t2 --> i3
    l1 --> l2

The diagram represents relationships declared in the owned files, not a complete runtime pipeline.

Implementation details

pdf/src/FrameDecorator/Block.php manages line boxes.

  • reset initializes the collection with a new line box and resets the current-line index.
  • add_frame_to_line ignores frames that are not in flow and assigns eligible frames to the current line.
  • Inline frames act as wrappers. A br frame maximizes the current line and starts a new line.
  • Leading text on an empty line is trimmed when the frame is not preformatted.
  • Frames with zero margin width are skipped except for hr and preformatted content.
  • Frames that exceed the available line width cause a subsequent line to be created.
  • add_line creates the next line box, with a flag for explicit line breaks.

pdf/src/FrameReflower/Block.php defines block reflow.

  • reflow checks forced page breaks and returns when the page is full.
  • It generates content, collapses margins, calculates restricted width, stores the resulting width and horizontal offsets, and positions the frame.
  • It establishes the first line’s vertical position and containing-block geometry.
  • Children are processed in source order. Each child receives a containing block, clear handling is processed, and the child is reflowed.
  • Page-full checks stop further child processing. A page break after a child also stops the block’s child loop before later line and float work.
  • Block height and restricted vertical dimensions are calculated after child processing.

pdf/src/Positioner/Block.php contains position.

  • The x coordinate starts at the containing block’s x coordinate.
  • The y coordinate comes from the parent’s current line when a block parent exists; otherwise it uses the containing block’s y coordinate.
  • Non-floating blocks advance the parent line before taking its y coordinate.
  • Relative top and left offsets are applied before the frame position is set.

pdf/src/Renderer/Block.php contains render.

  • Effective opacity is applied and body height can be adjusted from the containing block.
  • Anchors with a nonempty href create canvas links.
  • The renderer draws rounded clipping, backgrounds, borders, and outlines.
  • Optional debug geometry covers block, padding, and line boxes.
  • An element with a nonempty id creates a named destination.

pdf/src/FrameDecorator/Inline.php handles inline continuations through split.

  • A null frame delegates splitting to the parent.
  • A frame that is not a child of the current inline frame raises an exception.
  • The node is cloned into a continuation inserted after the current inline frame.
  • The current frame loses right margin, padding, and border width; the continuation loses the corresponding left styles.
  • Non-repeating continuation backgrounds are suppressed.
  • The selected frame and following siblings move into the continuation, and moved frames are reset.
  • After those frames move, a forced page break or either matching page_break_before or page_break_after style on the last moved frame causes the parent split.

pdf/src/FrameReflower/Inline.php defines inline reflow.

  • Forced page breaks and page fullness are checked before further work.
  • Generated content is set and the inline frame is positioned.
  • Outer left and right edge styles are copied to the first and last text children.
  • When a block is supplied, the inline frame is added to that block’s current line.
  • Each child receives the inline containing block and is then reflowed.

pdf/src/Positioner/Inline.php contains position.

  • Inline positioning requires a block-level parent; otherwise it raises an exception.
  • Fixed-position ancestors bypass the ordinary inline line-fit check that can create a new line for nested text.
  • For a text child nested inside an inline frame, minimum width is compared with the remaining line width. If it does not fit, a new line is created.
  • The frame is placed at the current line’s accumulated width and y coordinate.

pdf/src/Renderer/Inline.php renders inline extents.

  • render returns when the frame has no children.
  • get_child_size recursively aggregates child padding-box widths and heights, stopping before a trailing standalone space.
  • Optional debug geometry records child border and padding boxes.
  • When style values permit, inline backgrounds/background images and borders are drawn across the calculated child extent; a nonempty id adds a named destination, and an anchor with a nonempty href adds a link.

pdf/src/FrameDecorator/ListBullet.php defines bullet dimensions.

  • get_margin_width and get_margin_height return zero when list_style_type is none.
  • Otherwise, both dimensions use the configured font size, BULLET_SIZE, and twice the fixed BULLET_PADDING.
  • get_width and get_height delegate to those margin calculations.

pdf/src/FrameReflower/ListBullet.php defines bullet reflow.

  • The bullet width is assigned from the decorator.
  • The bullet frame is positioned.
  • The bullet is added to the parent block’s current line only when list_style_position is inside.

pdf/src/Positioner/ListBullet.php contains position.

  • The bullet is placed to the left of its containing block by its own width.
  • Its vertical position starts at the parent’s current line.
  • When a next sibling exists, its line height contributes to a vertical offset.

pdf/src/Renderer/ListBullet.php contains render.

  • Split list items return before the following rendering branches.
  • When the unsplit renderer reaches the list-style-image branch, a valid, non-broken image uses its natural dimensions, DPI-based scaling, adjusted positioning, and a canvas image operation.
  • Without a usable list-style image, predefined markers are selected:
    • disc and circle use a canvas circle; the default branch follows the disc path.
    • square uses a filled rectangle.
  • Ordered styles use the dompdf-counter attribute and counter conversion for decimal, alphabetic, Roman, Greek, and compatibility forms.
  • When the unsplit renderer reaches an ordered-marker branch, a missing dompdf-counter or blank generated counter returns without drawing; a nonblank counter is drawn as text.
  • When rendering reaches the final check, a nonempty id creates a named destination.

pdf/src/FrameDecorator/Text.php exposes text-node content.

  • get_text returns the data value of the frame’s DOM node.
  • The decorator accepts text-node frames; non-text frames are rejected by its constructor.

pdf/src/FrameReflower/Text.php performs line layout and text reflow.

  • _layout_line derives height from font metrics.
  • capitalize, uppercase, and lowercase transforms are applied according to text_transform.
  • Whitespace handling distinguishes normal, pre, nowrap, pre-line, and pre-wrap.
  • Text width includes measured text plus margin, border, and padding contributions.
  • When content overflows the available line width, text is split and the frame width is recalculated.
  • Newline content also produces split behavior for the applicable whitespace modes.
  • reflow checks forced page breaks and page fullness, finds the block parent, positions the text frame, lays out its line, and adds it to the supplied block.
  • When layout reports that another line is required, block line creation follows the text insertion step.

pdf/src/Renderer/Text.php contains text render.

  • Text that trims to an empty string returns without drawing.
  • Nonblank text applies left margin, padding, and border offsets to its x coordinate.
  • The canvas receives the text with the selected font, color, word spacing, and character spacing.
  • Inherited underline, overline, and line-through decorations are drawn when present.

Updated