Skip to content

Wrap column text around a floated image - #511

Open
jakejackson1 wants to merge 1 commit into
gravitypdffrom
feature/float-images-in-columns
Open

jakejackson1 wants to merge 1 commit into
gravitypdffrom
feature/float-images-in-columns

Conversation

@jakejackson1

Copy link
Copy Markdown
Member

A floated <img> inside <columns> used to be set inline, because Img never set float while columns were active. It now floats as it does in normal flow, and the text of its own column wraps around it. This lets a template run a photo inside a column of an article, which a magazine layout needs.

<columns column-count="2" />
<p><img src="photo.jpg" style="float: right; width: 30mm"> Lorem ipsum…</p>

How

  • Pending floats are drawn when their column is left. The column is left through AcceptPageBreak(), NewColumn() or SetColumns(). Drawing a float there also clears floatmargins, so it never narrows lines in the next column.
  • Each float is filed under the column it was placed in. printColumnFloats() draws it into the column buffer ahead of the first line level with or below its top. Balancing assigns columns in buffer order, so the float then moves with the lines beside it.
  • Balancing never breaks a column beside a float. It skips break points inside a float's vertical extent ($columnFloats, besideColumnFloat()), and a column's bottom reaches down to the float's margin.
  • Floats that don't fit. A float that can't fit in the rest of its column moves to the next one, as a line would. An image too tall or too wide for an empty column is still set inline, exactly as before.

Limits

  • Floated images only. Floated <div>s in columns are still laid out as blocks.
  • With vAlign="J", stretching a column also stretches the image vertically, up to max_colH_correction, as it already did for inline images.
  • Image borders aren't drawn in columns (PaintImgBorder() returns early), so a floated image's border doesn't show there either.

Tests

  • FloatImageInColumnsTest reads the balanced page stream. It checks that lines level with the image in its column are clear of it, and that every other line, including lines level with it in the other column, starts at its column's edge. It covers:
    • left and right floats, LTR and RTL
    • balanced columns, vAlign="J", keepColumns and <columnbreak>
    • seven lead lengths, so the image lands at the top, middle, bottom of the first column and past it
  • Further tests check that an oversized image falls back to inline, and that the column's bottom reaches the image's margin.
  • Turning off each part of the fix in turn makes these tests fail.
  • A new snapshot, float-images-in-columns, shows a two-column article with a right float in mid-paragraph and a left float. The existing columns snapshot is unchanged.
  • composer test passes (4107 tests; 5 skipped for missing ICU data). phpcs and PHPStan are clean.

🤖 Generated with Claude Code

A floated image inside <columns> was always set inline. It now floats as
it does in normal flow, wrapping the lines of its own column only:

- Pending floats are drawn when their column is left (AcceptPageBreak,
  NewColumn, SetColumns), which also clears the float margins so they do
  not narrow lines in the next column.
- Each float is filed in the column buffer ahead of the lines beside it
  and under the column it was placed in, so balancing moves it with them.
- Balancing ignores break points inside a float's vertical extent, and a
  column's bottom reaches down to the float's.
- An image too tall or too wide for an empty column is still set inline.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant