-
Notifications
You must be signed in to change notification settings - Fork 3.3k
LibPDF: Add basic tiled, coloured pattern rendering #22197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
nico
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is is super cool!
The PaintStyle change looks extremely clean. However, we use the ColorSpace machinery for transforming images too (cf Renderer::load_image() towards the end) and I worry a bit that creating one PaintStyle object per call to style() will make performance even harder to optimize.
Maybe we should instead just special-case Pattern in Renderer more and do a bunch of is pattern then call style else call color or something like that?
Also, do you think we could pass Renderer to create() and have the Pattern object remember it, instead of passing it to style() all the time?
Finally, the "preferences" object is for user-settable things I think. Maybe we can add a parameter for the bg color?
|
Perhaps we could have the style function return a |
This is in anticipation of Pattern color space support which does not yield a simple color.
RepeatingBitmapPaintStyle tiles a bitmap passed on passed in parameters and paints according to that. OffsetPaintStyle offsets an existing paint style and paints with that. These two will be useful in the PDF renderer.
|
Made changes based on feedback :) I do recognise the difference in semantics between checking if the |
nico
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great!
lgtm as-is; some pontificating below (but feel free to ignore; up to you).
|
Also, I don't remember if Serenity's PDF viewer supports page zoom (MacPDF doesn't yet). Might be worth thinking about if the pattern rasterization applies zoom at the right layer, so that zooming in doesn't make the pattern pixelated. |
So the way I decided on the size for the bitmap for rasterization was to take the pattern bounding box and transform it to device space with the CTM (ETA: after first mapping it to user space with the pattern matrix). This seems to handle scaling nicely, and intuitively I think it's right, but frankly I did a lot of throwing random matrices at the wall to see what stuck so I could be missing something. |
This is based largely on Adobe's EXAMPLE 2 on p176 of the specification, manually edited slightly and then cleaned up with mutool. https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/PDF32000_2008.pdf
While working on SerenityOS#26292, I noticed that while fills/strokes can be Gfx::PaintStyles in LibPDF, currently they never are, which confused me. It turns out that a few years ago, tiled patterns were implemented in PR SerenityOS#22197, but were partially reverted due to crashes in SerenityOS#22364, leaving around a partial implementation. It appears the author was going to look into the crashes, but never got around to it. So, this patch resolves all the crashes on `0000.zip`, mainly by checking types and not assuming dictionary keys exist. Summary of `./Meta/test_pdf.py ~/Downloads/0000`: ``` Stacks: 0 crashes (0.0%) 0 distinct crash stacks 7 failed to open (0.7%) /home/macdue/Downloads/0000/0000346.pdf /home/macdue/Downloads/0000/0000202.pdf /home/macdue/Downloads/0000/0000399.pdf /home/macdue/Downloads/0000/0000421.pdf /home/macdue/Downloads/0000/0000480.pdf /home/macdue/Downloads/0000/0000920.pdf /home/macdue/Downloads/0000/0000819.pdf 3 files with password (0.3%) 909 files without issues (90.9%) ```
This reverts commit 6032c06. This relands the original commit with fixups to make `PatternColorSpace` more robust to unexpected inputs. While working on SerenityOS#26292, I noticed that while fills/strokes can be Gfx::PaintStyles in LibPDF, currently they never are, which confused me. It turns out that a few years ago, tiled patterns were implemented in PR SerenityOS#22197, but were partially reverted due to crashes in SerenityOS#22364, leaving around a partial implementation. It appears the author was going to look into the crashes, but never got around to it. So, this patch resolves all the crashes on `0000.zip`, mainly by checking types and not assuming dictionary keys exist. Summary of `./Meta/test_pdf.py ~/Downloads/0000`: ``` Stacks: 0 crashes (0.0%) 0 distinct crash stacks 7 failed to open (0.7%) /home/macdue/Downloads/0000/0000346.pdf /home/macdue/Downloads/0000/0000202.pdf /home/macdue/Downloads/0000/0000399.pdf /home/macdue/Downloads/0000/0000421.pdf /home/macdue/Downloads/0000/0000480.pdf /home/macdue/Downloads/0000/0000920.pdf /home/macdue/Downloads/0000/0000819.pdf 3 files with password (0.3%) 909 files without issues (90.9%) ``` Co-authored-by: MacDue <[email protected]>
This reverts commit 6032c06. This relands the original commit with fixups to make `PatternColorSpace` more robust to unexpected inputs. While working on #26292, I noticed that while fills/strokes can be Gfx::PaintStyles in LibPDF, currently they never are, which confused me. It turns out that a few years ago, tiled patterns were implemented in PR #22197, but were partially reverted due to crashes in #22364, leaving around a partial implementation. It appears the author was going to look into the crashes, but never got around to it. So, this patch resolves all the crashes on `0000.zip`, mainly by checking types and not assuming dictionary keys exist. Summary of `./Meta/test_pdf.py ~/Downloads/0000`: ``` Stacks: 0 crashes (0.0%) 0 distinct crash stacks 7 failed to open (0.7%) /home/macdue/Downloads/0000/0000346.pdf /home/macdue/Downloads/0000/0000202.pdf /home/macdue/Downloads/0000/0000399.pdf /home/macdue/Downloads/0000/0000421.pdf /home/macdue/Downloads/0000/0000480.pdf /home/macdue/Downloads/0000/0000920.pdf /home/macdue/Downloads/0000/0000819.pdf 3 files with password (0.3%) 909 files without issues (90.9%) ``` Co-authored-by: MacDue <[email protected]>


LibPDF vs PDF.js :)
So I've added some basic pattern rendering to LibPDF, mainly targeting Adobe's example on p176 of the spec (pictured above). There's a couple structural-y changes that I'm not too sure about:
Also my C++ is a bit rusty (in more ways than one) so let me know if there's better ways to do things :)