Skip to content
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

Raster image not rendered in some cases when in a repeating pattern. #5539

Closed
SimonSapin opened this issue Dec 13, 2014 · 3 comments
Closed

Comments

@SimonSapin
Copy link

Initially reported as Kozea/WeasyPrint#232

Test case

Here https://pdf.yt/d/HVZGpPmFKSeiJJjC is a PDF file created with WeasyPrint from this HTML/CSS code:

<style>dd { border: thin solid; height: 120px } dt { margin-top: 1em }</style>
<dl>

<dt>&lt;img>
<dd><img src="logo.png">

<dt>background no-repeat
<dd style="background: url(logo.png) no-repeat">

<dt>background repeat-x
<dd style="background: url(logo.png) repeat-x">

<dt>background repeat-y
<dd style="background: url(logo.png) repeat-y">

<dt>background repeat
<dd style="background: url(logo.png) repeat">

Expected result

Here it is rendered correctly by Evince/poppler:
evince

Actual result

… and rendered incorrectly by pdf.js. Some images are missing:
pdfjs

What’s going on in the test case

WeasyPrint uses cairo to produce PDF files. It loads a PNG image into an ImageSurface (a bunch of uncompressed RGBA pixels in memory). In the <img> case, that ImageSurface is painted directly on the final PDFSurface, no problem.

background-image is more complicated because background-repeat can have two different values for the X and Y dimensions, but cairo’s repetition of patterns is in both dimensions or none. The image is first painted on an intermediate surface that can be larger than the image, which is then painted on the final PDFSurface after setting CAIRO_EXTEND_REPEAT on the pattern (even if both dimensions are no-repeat, to keep a single code path). The intermediate surface is also a PDFSurface, on the assumption that something vector-based can be "lossless" and avoid double rasterization.

Let’s assign blame

Do the internals of this PDF file look busted to y’all? I know my way around the PDF file format enough to add outlines and links/annotations, but I’m less familiar with images and repeating patterns.

pdf.js is apparently not the only tool having trouble with this kind of file: Kozea/WeasyPrint#222 reports that when opening a WeasyPrint-generated PDF file in Photoshop, background images do not show up as available images (but <img> images do). So maybe cairo is buggy and does something weird in the generated PDF file in some cases?

In Evince, I can drag-and-drop images from <img> and extract a PNG file from a PDF file, but not for images from background-image.

I could also change WeasyPrint to avoid using an intermediary surface when possible (for background-repeat: no-repeat and repeat. That is, most cases.) Would that help?

@yurydelendik
Copy link
Contributor

but I’m less familiar with images and repeating patterns.

http://brendandahl.github.io/pdf.js.utils/browser/ might help you there

Looks like it's painting those images but outside of the clipped region. (Could be logic around transformation of BBox values)

@THausherr
Copy link
Contributor

The link on top of this issue no longer works.

@SimonSapin
Copy link
Author

I’ve re-rendered the same HTML/CSS source with WeasyPrint: test.pdf, and it now renders correctly in pdf.js shipped with Firefox 59.0.2. However this is likely a different WeasyPrint version, so I don’t know if WeasyPrint has changed what PDF data it emits for this source or if this was a pdf.js bug that has since been fixed. Either way, I don’t think there’s much more to do here.

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

No branches or pull requests

4 participants