Skip to content

fix(xlsx): cap a line legend key's marker at six tenths of the legend font size - #1752

Merged
developer0hye merged 1 commit into
mainfrom
fix/issue-1617-legend-marker-cap
Sep 15, 2026
Merged

developer0hye merged 1 commit into
mainfrom
fix/issue-1617-legend-marker-cap

Conversation

@developer0hye

Copy link
Copy Markdown
Owner

File submission policy

Summary

A line series' legend key drew the series' own marker at the declared c:marker/c:size whatever the legend's font size, so the 6pt bottom legend of the public Gift Budget workbook carried a 5pt disc (4.10 printed points) where native Excel prints 3pt (2.46), and the 5pt sample box outgrew the 6pt line box and pushed the Amount Spent label 1.06 printed points below the three column labels.

Native Excel for Mac 16.112 one-factor exports (the series declaring a 24pt marker under legend sizes 6, 7, 8, 9, 10, 11, 12, 14 and 18pt on Segoe UI and 6, 8, 10, 12 and 14pt on Verdana; declared markers 2, 3, 5, 7 and 12 at 9pt and 2, 4, 5 and 7 at 6pt; each batch against a layout-identical re-zip control) show that the key marker is the declared size capped at floor(0.6 x legend size), face-independent: 3, 4, 4, 5, 6, 6, 7, 8, 10 chart points. The painted key rectangle (0.45 x the face's hhea box) is not the cap — at 10pt it is 5.985pt on Segoe UI and 5.470pt on Verdana while the marker is 6pt on both. Declared sizes under the allowance pass through, and the plotted markers keep their declared size in every export.

line_legend_key now takes the legend text size, draws the plot's marker at min(declared, legend_marker_cap_pt(size)), and sizes its sample box at min(SERIES_MARKER_SIZE_PT, cap) so the box shrinks with the allowance but never grows past the 5pt the key's baseline offset is calibrated against. series_marker_markup takes the size as a parameter; the plot passes the declared size through the new series_marker_size_pt. The 9pt fixture output is byte-identical before and after.

On the 6pt package the key marker now measures 3.0 x 3.0 chart points (2.46 printed) against native 3.0 x 3.0, and all four legend labels share one baseline as native does.

Related: #1617. The disc's whole-point origin within the sample is #1618; the row's one-chart-point seat is #1748; the 2.0pt native sample stroke at 6pt is #1751, filed from this audit with assets/bugfixes/issue-1751/compare.jpg.

Related issue

Fixes #1617

Testing

  • Red: a_legend_marker_never_exceeds_six_tenths_of_the_legend_font_size, a_declared_marker_below_the_legend_cap_keeps_its_size, a_small_legend_shrinks_the_line_sample_box_with_its_marker and the_legend_marker_cap_reaches_every_family_that_draws_a_line_key fail on main (5pt disc at every legend size).
  • declared_marker_paint_reaches_plot_and_legend_across_chart_families now expects the key marker at the legend's allowance while its paint still reaches the key.
  • cargo test --locked -p office2pdf --lib: 3089 passed.
  • cargo test --locked --workspace: all suites passed (office2pdf lib 3124; conversion 189, workspace integration suites green; 0 failed).
  • cargo clippy --locked --workspace --all-targets -- -D warnings on stable and 1.97, cargo fmt --all --check, git diff --check: passed.
  • Fresh native/current PDFs of the 6pt package (native export of the exact controlled package, SHA-256 3f40e2a8…): compare_layout.py --audit --fine-shift 0.5 --noise-floor 0.5, compare_text_layer.py, compare_render.py --dpi 300 --strict-clusters on page 2; the text-layer census (3 fewer spaces, extraction order) is unchanged from the XLSX: small-font bottom legends use an incorrect entry-width floor #1616 audit.
  • Required delegated read-only documentation freshness audit: PASS.
  • Probe specs, package and export hashes, and the measured rows: validation.

Visual impact

  • No rendered PDF change
  • Rendered PDF change or visual evidence added

Visual audit

Visual comparison

GT Before After
GT Before After

Required inspection

  • Rendered all evidence at 150 DPI or higher
  • Stored progressive JPEG quality 86 assets with metadata stripped
  • Used Codex/Claude vision to inspect the full GT/output pages, diff, and matched crops
  • Inspected matched region crops at full resolution
  • Ran compare_layout.py --audit --fine-shift PT and dispositioned every fine/large text-instance shift, rectangle geometry deviation, painted-text visibility mismatch, and visible-fill occlusion
  • Ran compare_render.py --cluster-report PATH --strict-clusters and dispositioned every material 5% fuzz diff cluster by explicit ID
  • Inventoried hairlines and border dash styles
  • Inventoried font weight, italic, and underline emphasis

Deviation audit

Check Result
Page count/order Matches GT
Element presence Matches GT
Position/size Remaining: #1618 (disc origin within the sample), #1719 (sidebar text origin), #1659 (long-string drift); the 6pt legend key marker is fixed at 3 chart points and the line series' label now shares the row baseline
Rotation/flip No deviation observed
Fill Matches GT
Stroke/border Remaining: #1751 (6pt legend sample stroke 2.24pt against native 2.0pt), #1745 (zero-value line segments unclipped at the plot edge)
Shape outline geometry Matches GT
Text content Matches GT
Font family/weight/style Matches GT
Text color Matches GT
Alignment Matches GT
Line/paragraph spacing Remaining: #1748 (the 6pt legend row seats one chart point below native)
Clipping/overflow Remaining: #1745

Checklist

  • Commits include a Signed-off-by line
  • PR scope contains one root cause
  • Remaining converter or harness deviations each reference an open issue

🤖 Generated with Claude Code

… font size

A line series' legend key drew the series' declared marker size whatever the
legend's font size, so a 6pt worksheet legend carried the 5pt plot marker where
native Excel prints 3pt, and the 5pt sample box outgrew the 6pt line box and
pushed that entry's label a printed point below the column labels on its row.

Native Excel for Mac 16.112 one-factor exports of the public gift-budget
workbook (a 24pt declared marker under legend sizes 6 to 18pt on Segoe UI and
Verdana, plus declared markers 2 to 12 at 9pt and 2 to 7 at 6pt) show the key
marker is min(declared, floor(0.6 x legend size)), independent of the face:
the painted key rectangle is 5.985pt on Segoe UI and 5.470pt on Verdana at
10pt while the marker is 6pt on both. The plotted markers keep their declared
size in every export.

The legend key now takes the legend text size, draws the plot's marker at that
allowance, and sizes its sample box at min(5pt, allowance) so ordinary-size
legends keep their calibrated seat. The 9pt fixture output is byte-identical.

Evidence for the fixed 6pt page (assets/bugfixes/issue-1617) reuses the #1616
cluster dispositions by identical ID; the 2.0pt native sample stroke at 6pt is
filed as #1751 with its compare image. Probe specs and the measured native rows
are recorded under assets/validation/issue-1617.

Related: #1617, #1751, #1618, #1748.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Yonghye Kwon <developer.0hye@gmail.com>
@developer0hye
developer0hye merged commit a3c751b into main Sep 15, 2026
18 checks passed
@developer0hye
developer0hye deleted the fix/issue-1617-legend-marker-cap branch September 15, 2026 15:44
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.

XLSX: small-font legends retain oversized line-series markers

1 participant