Closed Lucas-C closed 5 months ago
Would like to work on it, if no one else is working.
Would like to work on it, if no one else is working.
You are very welcome, go on!
hello, if its available can I work on it?
Ping @JDeepD: have you started working on this, or are you planning to do so soon? If so, great! 😊 Any help needed? Else, would you be OK to leave it for @Aashish-Upadhyay-101 to work on it?
I am planning to work on this soon. Since I have not contributed to fpdf2 before, I am looking into some code and documentation. But @Aashish-Upadhyay-101 can work on it as I would probably need some more time to understand the codebase and begin working on it.
nice, before starting I have a few questions @Lucas-C do I have to create bezier() method from scratch ?
I am planning to work on this soon. Since I have not contributed to fpdf2 before, I am looking into some code and documentation. But @Aashish-Upadhyay-101 can work on it as I would probably need some more time to understand the codebase and begin working on it.
@JDeepD : thank you for you answer. If @Aashish-Upadhyay-101 creates a PR first, you input will be welcome as a reviewer on it!
do I have to create bezier() method from scratch ?
@Aashish-Upadhyay-101 yes, no method exist at this moment.
@Lucas-C, I have to make function that renders bezier curve. To actually render on the pdf which function or library this project is using? I think drawing.py has some functions inside it, right?
I think drawing.py has some functions inside it, right?
As mentioned in the issue description, the drawing.py module has several classes that implement the geometric calculations:
It might be easiest to just create a wrapper around one (or several) of those.
Actually, I think that several of our bespoke geometry methods could be simplified by calling the drawing.py module instead of doing the work themselves.
I'm new to open source and really struggling to do this....! can you help?
Hi @Aashish-Upadhyay-101, and welcome. I am going to be a bit busy for a few days, but I should have some time on Monday to give you some pointers. Those pages are good starting points if you are new:
Could you try to explain precisely on what points you are struggling?
Usually, when contributing to an open source project, the first steps are :
git
pip
(following the instructions on the page I mentioned above)pytest
)test/shapes/test_bezier.py
file seems pertinent) by taking inspiration from the existing ones. You will want to call assert_pdf_equal()
with generate=True
while developping your new test, to generate a new reference PDF file@Lucas-C I tried to Setup locally, but got error when I run test
i ran pytest -p test
As I'm purely a beginner and really want to success in this area, I will do whatever it takes to learn so please guide me through
Or maybe you can assign me a little bit biginner friendly simple issue to get started with?
@Lucas-C I tried to Setup locally, but got error when I run test
1. first of all the test failed with errors
i ran
pytest -p test
Did you install the requirements first?
Install dependencies using pip install -r test/requirements.txt
2. After that i'm also confused where to start like from where should i began.
The docs/Development.md
is a pretty good starting point.
3. Afer that, I'm also confused which file to modify and how to add bezier() function
The codebase should generally remain uniform. See how other functions are implemented and try to implement the bezier()
function in a similar manner.
@JDeepD I got this error message when I tried to install the requirements.txt
@JDeepD I got this error message when I tried to install the requirements.txt
First thing that you should do when you get errors is to google it and try out some top solutions.
For ex, the error here is error: command swig failed...
After a bit of googling, this is what I found.
@JDeepD now everything is setup, now I will try to implement bezier
@JDeepD can you help me with bezier() function. I created a empty function inside fpdf's class FPDF like this
def bezier(self, point_list, style):
pass
but don't know afterwards how to implement it, can you guide me
@JDeepD can you help me with bezier() function. I created a empty function inside fpdf's class FPDF like this
def bezier(self, point_list, style): pass
but don't know afterwards how to implement it, can you guide me
You need to read some internal code for it. See the links mentioned in the top comment by Lucas.
@JDeepD I think if you have already understanded the code base, you can work on this issue. I'm just a beginner and like literally no idea whats going on the project
@Aashish-Upadhyay-101 If you have left working on this issue, then please let us know.
@JDeepD I left working on this issue, I think I need some more time to understand whats going on.
I would like to work on this issue? Just let me know.....
Great!
Feel free to drop a comment if you start working on this. I also suggest to quickly submit a pull request, as a draft, so that you can share your ongoing work.
Also, thank you for your help & answers here @JDeepD!
And thanks for your interest in fpdf2
, your contributions will be very welcome 😊
@all-contributors please add @JDeepD for question
I've begun work on this issue. I've opened draft PR (#596) so that I can share my progress.
From what I understand, here is my approach:
Add a public method to class fpdf
called bezier
. This method has 1 required arguments.
point_list
: Must contain atleast 4 points. The first and last set of coordinates are taken as the starting and ending points respectively. The remainder of the points are used as control points for the Bezier curve.
The Bezier curve methods created in #196 can't be used here as they are for the case of 2 control points only. However, they can be seen as a special case of the general Bezier curve with arbitrarily many control points. My revised plan is to write a more general Bezier curve method of which the original methods will be special cases.
This method will take a list of two or more points. The method will simply iterate over this set of points and render bezier curves using the methods created in PR #196.
I notice that in the description of the issue, the method should also take a style argument. Given that we are rendering a line (which may not necessarily be closed unless the last point is the same coordinates as the first point), does it make sense to have style options that we would normally have for closed shapes (such as fill and draw).
does it make sense to have style options that we would normally have for closed shapes
As can be seen in the CodePen snippet on the following page, yes bezier curves with filling make sense: https://www.sitepoint.com/html5-svg-cubic-curves/
Your plan sounds great 😊
It is important that, to draw those curves, the same code is used in this method and in the drawing
module of fpdf2
, to avoid code duplication.
I see. I read through some of the implemented methods in the drawing
module and realized that all I need to do is to generate the string representing the complete Bezier curve (as in the examples you linked) that can be passed to the path render function. Does that solution make sense?
all I need to do is to generate the string representing the complete Bezier curve (as in the examples you linked) that can be passed to the path render function. Does that solution make sense?
Yes, absolutely 😊
In bezier()
you can use the existing drawing_context() or new_path() methods that can be used as context managers
@jeettrivedi, you might want to check out the svg.py module and compare how it uses the bezier methods in drawing.py. You can probably keep it simpler than that because you don't need to deal with other path elements, but the parts handling curves (especially continuous curves) may still be useful to study.
@jeettrivedi: are you still working on this issue? If you do, can I help you with anything? If not, no worries, please just notify us 😊
@jeettrivedi: are you still working on this issue? If you do, can I help you with anything? If not, no worries, please just notify us blush
Hey, I am actively working on it right now. I will have questions likely next week. Thank you for checking in!
Hey, I am actively working on it right now. I will have questions likely next week. Thank you for checking in!
Great!
@Lucas-C I have a question. So far, I wrote a simple method to generate the path string for a bezier curve given the points and the method then passes that path string to the method fpdf._out
. I wrote a test to see whether this produces the output I am expecting.
While debugging this, I examined the path string (after unit transformations) that is passed to fpdf._out
by fpdf.rect
. Here's an example
283.46 558.43 283.46 -141.73 re B
I tried to look for an re
or B
operator for SVG paths but didn't find any information. Could you maybe elaborate on what these are? I was looking at (this page)[https://www.w3schools.com/graphics/svg_path.asp] for SVG path information. I also attempted to render the above mentioned path string in an online SVG path renderer but it only gave me a vertical line. I maybe have misunderstanding something minor. Thanks in advance!
You can check the annex A of the 1.7 PDF spec for the meaning of PDF operators.
B
is the fill & stroke operator in PDF syntax.
Hi @jeettrivedi Was my answer helpful to you? Were you able to perform those path drawing tests?
Without news from @jeettrivedi, and given that no PR is currently open regarding this, I think that this feature is up-for-grabs, anyone willing to contribute can work on this!
Hello, just wondering if this is still up for grabs? I am interested in working on this.
Hello, just wondering if this is still up for grabs? I am interested in working on this.
Yes, you can work on implementing this feature, a PR would be welcome!
👍
I'm set up and have started working on this. I have some questions about how I should implement this.
the drawing.py module has several classes that implement the geometric calculations:
[BezierCurve()](https://github.com/PyFPDF/fpdf2/blob/4bcd4559ac9dea1f1e2d12a96f934fa5643983ee/fpdf/drawing.py#L2015) [RelativeBezierCurve()](https://github.com/PyFPDF/fpdf2/blob/4bcd4559ac9dea1f1e2d12a96f934fa5643983ee/fpdf/drawing.py#L2087) [QuadraticBezierCurve()](https://github.com/PyFPDF/fpdf2/blob/4bcd4559ac9dea1f1e2d12a96f934fa5643983ee/fpdf/drawing.py#L2167) [RelativeQuadraticBezierCurve()](https://github.com/PyFPDF/fpdf2/blob/4bcd4559ac9dea1f1e2d12a96f934fa5643983ee/fpdf/drawing.py#L2260)
It might be easiest to just create a wrapper around one (or several) of those.
These seem to be used by PaintedPath. Should FPDF2.bezier() create a PaintedPath object?
with self.drawing_context(debug_stream=debug_stream) as ctxt:
path = PaintedPath(x=x, y=y)
path.style.paint_rule = paint_rule
yield path
ctxt.add_item(path)
It looks like in order to add a shape to the document, other methods are getting a drawing context and then using the context's add_item
method, like here. Should bezier() work like this?
Thanks in advance. This will be my first significant (taking >10min) FOSS contribution, so the codebase is imposing, but the code makes sense and I will keep reading and playing with the code to figure out as much as possible on my own and ask questions when needed.
These seem to be used by PaintedPath. Should FPDF2.bezier() create a PaintedPath object?
That seems like a valid approach to me, yes!
You could also consider using with self.new_path(): ...
It looks like in order to add a shape to the document, other methods are getting a drawing context and then using the context's
add_item
method, like here. Shouldbezier()
work like this?
Yes. You can take inspiration from the usages of .new_path()
& PaintedPath()
in fpdf/svg.py
.
Thanks in advance. This will be my first significant (taking >10min) FOSS contribution, so the codebase is imposing, but the code makes sense and I will keep reading and playing with the code to figure out as much as possible on my own and ask questions when needed.
Sorry for the delay in answering you 😞 We want to welcome new FLOSS contributors on this project, so I will try to be quicker to answer all that questions you may have! 🙂
Thanks for your advice. I will get back on this this week!
Update: Have wrote an early version that uses PaintedPath.curve_to
or PaintedPath.quadratic_curve_to
depending on whether 2 or 3 tuples were given.
Python 3.11.8 (main, Feb 12 2024, 14:50:05) [GCC 13.2.1 20230801] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from fpdf import FPDF
>>> pdf = FPDF()
>>> pdf.add_page()
>>> pdf.set_draw_color(200, 5, 5)
>>> pdf.bezier([(50, 50), (90, 45), (60, 100)])
>>> pdf.set_draw_color(5, 5, 200)
>>> pdf.bezier([(150, 150), (190, 145)])
>>> pdf.output("beztest.pdf")
Glad to have a function doing something and will report back as I work toward having this do exactly what is intended.
Glad to have a function doing something and will report back as I work toward having this do exactly what is intended.
Good job @awmc000! I'm eager to see your Pull Request 😊
I think we can close this issue? I'll be looking through the issues on this project, I'm interested in doing more.
Yup, the PR didn't use the standard phrasing of "fixes ###", so it didn't get closed automatically.
Documentation on Bézier curves:
There is some suggested usage example, once implemented, inspired by the existing polygon() method:
@torque already implemented bezier curves in PR #196 in order to support SVG: https://github.com/PyFPDF/fpdf2/blob/2.5.6/fpdf/drawing.py#L2016
The goal here is to expose this feature as a new public
FPDF
method.Of course, new unit tests should be added, as well as a new documentation section in
docs/Shapes.md
By implementing this feature you, as a benevolent FLOSS developper, will provide access to the large community of fpdf2 users to a standard and useful PDF functionality. As a contributor you will get review feedbacks from maintainers & other contributors, and learn about the lifecycle & structure of a Python library on the way. You will also be added to the contributors list & map.
This issue can count as part of hacktoberfest