Skip to content

Fix rounded rectangle rendering with thick borders and fill artifacts#1634

Merged
Lucas-C merged 5 commits intopy-pdf:masterfrom
Ai-Chetan:fix/rounded-rect-rendering-issues
Oct 23, 2025
Merged

Fix rounded rectangle rendering with thick borders and fill artifacts#1634
Lucas-C merged 5 commits intopy-pdf:masterfrom
Ai-Chetan:fix/rounded-rect-rendering-issues

Conversation

@Ai-Chetan
Copy link
Copy Markdown

@Ai-Chetan Ai-Chetan commented Oct 20, 2025

Fix: Rounded rectangle rendering issues with thick borders and fill artifacts

Fixes #1632

Fixes rendering bugs in rectangles with rounded corners where thick borders caused arc positioning issues and fill colors showed visible line artifacts at corners.

🐛 Problem

When rendering rectangles with rounded corners using rect(..., round_corners=True), two visual issues occurred:

  1. Thick border positioning issue: With borders ≥ 2pt line width, the inner and outer arcs of corner circles were misaligned, creating visual distortions
  2. Fill artifacts: Rectangles with background colors showed small visible lines at each corner where fill met the border

Reproduction code:

from fpdf import FPDF

pdf = FPDF()
pdf.add_page()

# Thick border - shows positioning issue
pdf.set_draw_color(0, 0, 0)
pdf.set_fill_color(255, 255, 255)
pdf.set_line_width(6)
pdf.rect(50, 40, 120, 70, style='DF', round_corners=True, corner_radius=12)

# With background color - shows line artifacts
pdf.set_fill_color(230, 120, 125)
pdf.set_line_width(1)
pdf.rect(50, 160, 120, 70, style='DF', round_corners=True, corner_radius=12)

pdf.output("round_corners.pdf")

🔧 Root Cause

The _draw_rounded_rect() method drew each corner arc as a separate path operation with independent fill/stroke operations, then added separate lines for edges. This caused:

  • Multiple disconnected path segments instead of one continuous closed path
  • Each arc being stroked/filled independently, causing alignment issues with thick borders
  • Gaps and overlaps between path segments, creating visible artifacts

✅ Solution

Rewrote _draw_rounded_rect() to construct the entire rounded rectangle as a single continuous closed path:

  1. Added helper method _draw_arc_segment() that draws arc segments without starting a new path or applying styles
  2. Modified _draw_rounded_rect() to:
    • Start with a single m (move) command
    • Draw all edges and corner arcs as one continuous path using l (line) and c (curve) commands
    • Close the path with h and apply the style operator once at the end

Benefits:

  • ✅ Thick borders render correctly - entire shape stroked as one unit
  • ✅ Fill artifacts eliminated - single fill operation for complete closed path
  • ✅ More efficient PDF output (fewer operators)
  • ✅ Maintains backward compatibility

🧪 Testing

Automated tests:

# Run the new tests for this fix
pytest test/shapes/test_round_corners_fix.py -v

# Run all rounded corner tests
pytest test/shapes/test_rectangle.py -k round_corners -v

# Run all shape tests
pytest test/shapes/ -v

Manual validation:

# Generate visual validation PDF
python scripts/validate_round_corners_fix.py

Added comprehensive test suite in test/shapes/test_round_corners_fix.py with 3 test cases:

  • test_round_corners_thick_border - Verifies thick borders render without positioning issues
  • test_round_corners_fill_no_artifacts - Verifies filled corners have no visible line artifacts
  • test_round_corners_combined_issue - Tests both issues together

All existing rounded corner tests updated and passing ✅

📝 Changes

Modified:

  • fpdf/fpdf.py - Rewrote _draw_rounded_rect(), added _draw_arc_segment() helper method
  • test/shapes/class_round_corners_rect.pdf - Updated reference PDF
  • test/shapes/class_round_corners_rect_conditionals.pdf - Updated reference PDF
  • test/shapes/class_round_corners_rect_draw_color.pdf - Updated reference PDF

Added:

  • test/shapes/test_round_corners_fix.py - New test file with 3 comprehensive tests
  • test/shapes/round_corners_thick_border.pdf - Reference PDF for thick border test
  • test/shapes/round_corners_fill_no_artifacts.pdf - Reference PDF for fill artifacts test
  • test/shapes/round_corners_combined_fix.pdf - Reference PDF for combined test
  • scripts/validate_round_corners_fix.py - Visual validation script

✔️ Checklist

  • A unit test is covering the code added / modified by this PR
  • In case of a new feature, docstrings have been added, with also some documentation in the docs/ folder (N/A - bug fix)
  • A mention of the change is present in CHANGELOG.md
  • This PR is ready to be merged

Visual comparison:

Before (with bugs):

  • Thick borders show misaligned corner arcs
  • Fill colors show visible lines at corners
image

After (fixed):

  • Smooth, perfectly aligned corners with thick borders
  • Clean fills with no artifacts
image

Run python scripts/validate_round_corners_fix.py to generate a validation PDF demonstrating the fix.

By submitting this pull request, I confirm that my contribution is made under the terms of the GNU LGPL 3.0 license.

Copy link
Copy Markdown
Collaborator

@andersonhc andersonhc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see comments
Also, the lint job is failing. Please run black and pylint before the next commit.

Copy link
Copy Markdown
Member

@Lucas-C Lucas-C left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work, good job 👍

I asked for 2 extra tests, but appart from that this seems good to me 🙂

@andersonhc
Copy link
Copy Markdown
Collaborator

@allcontributors please add @Ai-Chetan for code

@allcontributors
Copy link
Copy Markdown

@andersonhc

I've put up a pull request to add @Ai-Chetan! 🎉

@andersonhc
Copy link
Copy Markdown
Collaborator

andersonhc commented Oct 21, 2025

@Ai-Chetan please add an entry on the CHANGELOG.md file, something like

### Fixed
* rendering of round rectangles that caused visual distortions and incorrect filling - thanks to @Ai-Chetan - [PR #1634](https://github.com/py-pdf/fpdf2/pull/1634)

We should be good to merge after that.

@Lucas-C Lucas-C merged commit db90706 into py-pdf:master Oct 23, 2025
23 checks passed
@Lucas-C
Copy link
Copy Markdown
Member

Lucas-C commented Oct 23, 2025

Merged!

Thank you very much @Ai-Chetan for your contribution 👍

@Lucas-C
Copy link
Copy Markdown
Member

Lucas-C commented Oct 29, 2025

This has just been released in the new published version 2.8.5:
https://github.com/py-pdf/fpdf2/releases/tag/2.8.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FPDF.rect: graphics issues with round corners

3 participants