Skip to content

fix: write the right valign-image for images - #451

Merged
webern merged 2 commits into
mainfrom
m/mxdev-valign
Sep 18, 2026
Merged

webern merged 2 commits into
mainfrom
m/mxdev-valign

Conversation

@webern

@webern webern commented Sep 18, 2026 •

Copy link
Copy Markdown
Owner

Human Summary

Honestly, this is pretty hard to understand, but there was a bug with valign attribute handling that was detected as a result of an audit looking for places to add Diagnostic messages to the mx::impl writer code.

Summary

<image> and <credit-image> write their vertical alignment with the valign-image vocabulary
(top, middle, bottom), not valign. setAttributesFromPositionData engaged the presence setter for
any authored alignment, which left valign-image at its natural zero of top, and its value setter
was silently compiled out because a core::Valign does not convert to the
std::optional<core::ValignImage> these elements hold. So <credit-image> wrote valign="top" for
every authored alignment, and a direction <image> wrote top for baseline.

A dedicated valign-image setter now writes the alignment at both call sites. baseline has no
valign-image counterpart, so it is left out rather than mapped to something else, and that case is
reported as droppedData. The reader never sets image valign, so round-trips did not show any of
this; the tests assert on the written XML instead.

Stacked on #450, a one-line build fix found while running these builds; this PR retargets to main
when that merges.

Testing

  • creditRoundTrip_imageValignMiddleWritesMiddle,
    creditRoundTrip_imageValignBaselineOmitsAttribute and
    ImageValignBaselineUnwritable_DirectionMarksRoundTrip all fail before the fix, each writing
    valign="top", and pass after
  • creditImageValignBaselineIsDropped checks the code, severity and message of the report
  • api tests: 5824 assertions in 647 test cases
  • api round-trip: 414 passed, 0 failed of 414 pinned, no baseline change
  • make test-all: core round-trip 841 test cases, core unit 322 assertions in 55 test cases
  • make fmt

References

@webern webern added bug software defect non-breaking fixes or implementation that do not require breaking changes impl Affects the mx::impl layer ai Issues opened by, or through, a coding agent. labels Sep 18, 2026
@webern
webern added this pull request to stack #453 September 18, 2026 05:26
Base automatically changed from m/mxdev-jobsenv to main September 18, 2026 06:56
<credit-image> and direction <image> use the valign-image vocabulary
(top, middle, bottom), not valign. setAttributesFromPositionData
engaged valign's presence flag for any authored alignment, but its
value setter silently no-ops for these elements (a core::Valign does
not convert to the std::optional<core::ValignImage> they expect), so
every authored alignment serialized as the leftover default "top".

Write the alignment through a dedicated valign-image setter instead,
omitting the attribute when unspecified or, for baseline, which
valign-image cannot express, and report the dropped baseline case as
a diagnostic rather than silently mapping it to something wrong.

Fixes #444.
droppedData is always reported as an error elsewhere; the two new
image-valign reports used warning. Reword the messages to say what
is not written, matching existing droppedData messages, instead of
naming the internal valign-image type. Add a WriteDiagnostics test
asserting the credit-image case's code, severity and message.
@webern
webern marked this pull request as ready for review September 18, 2026 16:36
@webern
webern merged commit 97c171d into main Sep 18, 2026
8 checks passed
@webern
webern deleted the m/mxdev-valign branch September 18, 2026 16:36
webern added a commit that referenced this pull request Sep 19, 2026
## Human Summary

Seems plausible that this is the correct way to read valign. This one
was both found and fixed by AI.

## Summary

Reading a `<credit-image>` threw its `valign` attribute away, so a
credit-image alignment did not
survive a round trip. `getImageData` in
`src/private/mx/impl/PageTextFunctions.cpp` discarded it on
purpose, because the generic `getPositionData` cannot read a picture's
alignment: a picture uses
`valign-image` (top, middle, bottom, no baseline) rather than the
`valign` a text element uses, and
the generic value getter is compiled out on the type mismatch, so a
present attribute came back as
the default `baseline`.

The read now happens off the element, in one helper shared with the
direction `<image>` reader:
`getImageValign` in `src/private/mx/impl/PositionFunctions.h`, next to
the writer's
`setImageValignFromVerticalAlignment`, called from both readers so they
cannot drift.
`DirectionReader::parseImage` loses its own inline switch, and the
`ValignImage.h` include it no
longer needs. An absent attribute still reads as unspecified, and this
reader never produces
baseline. The writer is unchanged. The comment in `PageImageData.h` that
said vertical alignment was
not modeled is corrected.

## Testing

- [x] New `creditRoundTrip.imageValignSurvives` fails before the fix
(top, middle and bottom all read back unspecified) and passes after
- [x] New `creditRoundTrip.imageValignIsReadFromXml` reads a spelled-out
`valign="middle"`; fails before, passes after
- [x] New `creditRoundTrip.imageValignAbsentStaysUnspecified`
- [x] `make api-test` passes (5891 assertions in 660 test cases)
- [x] `make api-roundtrip` passes with the newly pinned
`synthetic/credit-image.3.0.xml` (415 of 415 pinned)
- [x] `make api-roundtrip-discover`: 415 pass, 425 fail; before the fix
414 pass, 426 fail, credit-image.3.0.xml being the file the fix unlocked
- [x] `make test-all` passes (core round trip, core unit, api-test,
api-roundtrip)
- [x] `make fmt` and `make fmt-check`

## References

- Closes #454
- Related to #444, the writer side, merged as #451
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai Issues opened by, or through, a coding agent. bug software defect impl Affects the mx::impl layer non-breaking fixes or implementation that do not require breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

<image> and <credit-image> write valign="top" for other alignments

1 participant