Skip to content

Commit

Permalink
Doc: adding examples of bezier curves chaining (#1210)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas-C authored Jun 19, 2024
1 parent ddc72ff commit d574b07
Show file tree
Hide file tree
Showing 41 changed files with 74 additions and 17 deletions.
13 changes: 11 additions & 2 deletions docs/Shapes.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,18 +164,27 @@ pdf.output("solid_arc.pdf")
## Bezier Curve ##
_New in [:octicons-tag-24: 2.7.10](https://github.com/py-pdf/fpdf2/blob/master/CHANGELOG.md)_

Using [`bezier()`](fpdf/fpdf.html#fpdf.fpdf.FPDF.bezier) to create a cubic Bezier curve:
Using [`bezier()`](fpdf/fpdf.html#fpdf.fpdf.FPDF.bezier) to create a cubic Bézier curve:
```python
from fpdf import FPDF
pdf = FPDF()
pdf.add_page()
pdf.set_fill_color(r=255, g=0, b=255)
pdf.bezier([(20, 80), (40, 20), (60, 80)])
pdf.bezier([(20, 80), (40, 20), (60, 80)], style="DF")
pdf.output("bezier.pdf")
```

![](bezier.png)

One of the nice properties of Bézier curves is that they can be chained:

![](bezier-chaining.png)

Note that, for smooth joining cubic Bézier curves, neighbor control points around the joining point must mirror each other
(_cf._ [Wikipedia](https://en.wikipedia.org/wiki/Composite_B%C3%A9zier_curve#Smooth_joining)).

Source code: [test_bezier_chaining() in test_bezier.py](https://github.com/py-pdf/fpdf2/blob/master/test/shapes/test_bezier.py)

## Regular Polygon ##

Using [`regular_polygon()`](fpdf/fpdf.html#fpdf.fpdf.FPDF.regular_polygon):
Expand Down
Binary file added docs/bezier-chaining.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/table_with_gutter.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/table_with_images_and_img_fill_width.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion fpdf/drawing.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,10 @@ def rgb8(r, g, b, a=None):
Raises:
ValueError: if any components are not in their valid interval.
"""
if a is not None:
if a is None:
if r == g == b:
return DeviceGray(r / 255.0)
else:
a /= 255.0

return DeviceRGB(r / 255.0, g / 255.0, b / 255.0, a)
Expand Down
8 changes: 2 additions & 6 deletions fpdf/fpdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -1857,13 +1857,9 @@ def bezier(self, point_list, closed=False, style=None):
if points not in (3, 4):
raise ValueError(
"point_list should contain 3 tuples for a quadratic curve"
"or 4 tuples for a cubic curve."
" or 4 tuples for a cubic curve."
)

if style is None:
style = RenderStyle.DF
else:
style = RenderStyle.coerce(style)
style = RenderStyle.coerce(style)

# QuadraticBezierCurve and BezierCurve make use of `initial_point` when instantiated.
# If we want to define all 3 (quad.) or 4 (cubic) points, we can set `initial_point`
Expand Down
Binary file modified test/image/image_x_align_center.pdf
Binary file not shown.
Binary file modified test/image/image_x_align_right.pdf
Binary file not shown.
Binary file modified test/image/svg_image.pdf
Binary file not shown.
Binary file modified test/image/svg_image_alt_text_title.pdf
Binary file not shown.
Binary file modified test/image/svg_image_alt_text_two_pages.pdf
Binary file not shown.
Binary file modified test/image/svg_image_fit_rect.pdf
Binary file not shown.
Binary file modified test/image/svg_image_fixed_dimensions.pdf
Binary file not shown.
Binary file modified test/image/svg_image_no_dimensions.pdf
Binary file not shown.
Binary file modified test/image/svg_image_with_custom_size.pdf
Binary file not shown.
Binary file modified test/image/svg_image_with_custom_width.pdf
Binary file not shown.
Binary file modified test/image/svg_image_with_custom_width_and_no_dimensions.pdf
Binary file not shown.
Binary file modified test/image/svg_image_with_no_dimensions_and_custom_width.pdf
Binary file not shown.
Binary file added test/shapes/bezier_chaining.pdf
Binary file not shown.
65 changes: 57 additions & 8 deletions test/shapes/test_bezier.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ def test_quadratic_beziers(tmp_path):
pl5 = [[20, 230], (40, 280), (60, 250)]

pdf.set_fill_color(r=255, g=0, b=0)
pdf.bezier(pl1)
pdf.bezier(pl1, style="DF")
pdf.set_fill_color(r=0, g=255, b=0)
pdf.bezier(pl2)
pdf.bezier(pl2, style="DF")
pdf.set_fill_color(r=0, g=0, b=255)
pdf.bezier(pl3, closed=True)
pdf.bezier(pl3, style="DF", closed=True)
pdf.bezier(pl4, style="F")
pdf.bezier(pl5, style="D")

Expand All @@ -48,11 +48,11 @@ def test_cubic_beziers(tmp_path):
pl5 = [[20, 80], (40, 90), (60, 80)]

pdf.set_fill_color(r=255, g=0, b=0)
pdf.bezier(pl1)
pdf.bezier(pl1, style="DF")
pdf.set_fill_color(r=0, g=255, b=0)
pdf.bezier(pl2)
pdf.bezier(pl2, style="DF")
pdf.set_fill_color(r=0, g=0, b=255)
pdf.bezier(pl3, closed=True)
pdf.bezier(pl3, style="DF", closed=True)
pdf.bezier(pl4, style="F")
pdf.bezier(pl5, style="D")

Expand All @@ -70,12 +70,12 @@ def test_bezier_line_settings(tmp_path):

pdf.set_fill_color(r=255, g=0, b=0)
pdf.set_dash_pattern(dash=2, gap=3)
pdf.bezier(pl1)
pdf.bezier(pl1, style="DF")

pdf.set_fill_color(r=0, g=255, b=0)
pdf.set_dash_pattern(dash=4, gap=6)
pdf.set_line_width(2)
pdf.bezier(pl2)
pdf.bezier(pl2, style="DF")

# Reset for drawing points
pdf.set_line_width(0.2)
Expand All @@ -84,3 +84,52 @@ def test_bezier_line_settings(tmp_path):
draw_points(pdf, [pl1, pl2])

assert_pdf_equal(pdf, HERE / "bezier_curve_line_settings.pdf", tmp_path)


def test_bezier_chaining(tmp_path):
pdf = fpdf.FPDF()
pdf.add_page()
pdf.set_font("Helvetica", size=12)

pdf.x, pdf.y = 20, pdf.h / 4 - 30
pdf.cell(text="Chaining cubic curves:")
for i in range(4):
shift = 20 if i % 2 else -20
x1, y1 = (3 * i + 1) * pdf.w / 14, pdf.h / 4
x2, y2 = (3 * i + 2) * pdf.w / 14, pdf.h / 4 + shift
x3, y3 = (3 * i + 3) * pdf.w / 14, pdf.h / 4 + shift
x4, y4 = (3 * i + 4) * pdf.w / 14, pdf.h / 4
pdf.set_draw_color(
{
0: "#000",
1: "#f00",
2: "#0f0",
3: "#00f",
}[i % 4]
)
pdf.circle(x=x1 - 0.5, y=y1 - 0.5, r=1)
pdf.circle(x=x2 - 0.5, y=y2 - 0.5, r=1)
pdf.circle(x=x3 - 0.5, y=y3 - 0.5, r=1)
pdf.circle(x=x4 - 0.5, y=y4 - 0.5, r=1)
pdf.bezier(((x1, y1), (x2, y2), (x3, y3), (x4, y4)))

pdf.x, pdf.y = 20, pdf.h / 2 - 30
pdf.cell(text="Chaining quadratic curves:")
for i in range(4):
shift = 20 if i % 2 else -20
x1, y1 = (2 * i + 1) * pdf.w / 10, pdf.h / 2
x2, y2 = (2 * i + 2) * pdf.w / 10, pdf.h / 2 + shift
x3, y3 = (2 * i + 3) * pdf.w / 10, pdf.h / 2
pdf.set_draw_color(
{
0: "#f00",
1: "#0f0",
2: "#00f",
}[i % 3]
)
pdf.circle(x=x1 - 0.5, y=y1 - 0.5, r=1)
pdf.circle(x=x2 - 0.5, y=y2 - 0.5, r=1)
pdf.circle(x=x3 - 0.5, y=y3 - 0.5, r=1)
pdf.bezier(((x1, y1), (x2, y2), (x3, y3)))

assert_pdf_equal(pdf, HERE / "bezier_chaining.pdf", tmp_path)
Binary file modified test/svg/generated_pdf/Ghostscript_colorcircle.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/Ghostscript_escher.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/SVG_logo.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/SVG_logo_notransparency.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/arcs02.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/cubic01.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/cubic02.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/issue-1076.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/path_clippingpath.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/quad01.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/rgb-color-issue-480.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/search.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/transforms/matrix.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/transforms/multi.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/transforms/rotate.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/transforms/scale.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/transforms/skew.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/transforms/translate.pdf
Binary file not shown.
Binary file modified test/svg/generated_pdf/use-xlink-href.pdf
Binary file not shown.
Binary file modified test/text_region/tcols_3cols.pdf
Binary file not shown.
Binary file modified test/text_region/tcols_images.pdf
Binary file not shown.

0 comments on commit d574b07

Please sign in to comment.