-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
docx: use proper DPI for fallback PNG #9288
base: main
Are you sure you want to change the base?
Conversation
Draft pull request, because I'm not sure how you'd like to address this in the readers of other formats. BTW the ODT may need a fallback image stored too, if not when you open and save in LibreOffice it'll add one, but it'll be a very low resolution one too. |
6da581d
to
f06bb78
Compare
I think this is ready for review now:
One disadvantage that I can see:
I'd like to hear your thoughts on whether this is going in the right direction |
de4ec4d
to
136bb84
Compare
Two quick comments:
I'd like to see a more minimal patch without the PandocMonad change, or a stronger rationale for adding runConversion. |
Thanks, I'll add some comments about pagewidth, I think the units are points. Another approach that I considered (that avoids modifying PandocMonad) is to add a getPageWidth to Docx.hs, although this will perform some operations twice (parsing the reference.docx to figure out the size). The code to do that parsing can be factored out into a separate top-level function but it'll get called twice. |
Oh, I see now; you changed the type of svgToPng so it works with PandocMonad instead of MonadIO. |
What troubles me is that If we were okay with that, it would be cleaner, I think, just to require PandocMonad instances to be instances of MonadIO (so An alternative would be just to add |
I understand the desire the restrict what you can do (to avoid bugs and security issues). I can make the change to use svgToPng in the pandocmonad, shouldn't take long. |
Signed-off-by: Edwin Török <edwin@etorok.net>
This will be needed to run the conversion inside the PandocMonad, where we know the desired image size. The arguments are: (dpi, width, height). The width and height is optional to more easily convert existing code. [API change] Signed-off-by: Edwin Török <edwin@etorok.net>
Introduce getOrCreateFallback, and pass the desired size in points to rsvg-convert. Otherwise it'll guess the size based on the SVG's viewbox and completely ignore the DPI argument. Signed-off-by: Edwin Török <edwin@etorok.net>
Just look at --trace output. Can't use a golden test because the actual .png will be different depending on rsvg-convert version. Signed-off-by: Edwin Török <edwin@etorok.net>
Signed-off-by: Edwin Török <edwin@etorok.net>
The updated API changing commit is here: 682f972 I made both width and height optional to keep this commit smaller and the interface more flexible (should you want to revert back to the old behaviour then just pass I don't particularly like that there is a 4-tuple here instead of 4 arguments, but I couldn't figure out how to implement the various instances and Should I introduce a |
With one argument you can do e.g. putCommonState = lift . putCommonState but with four something like this should work: svgToPng w x y z = lift $ svgToPng w x y z |
Oh that is surprisingly simple, I was too caught up in trying to keep the LHS short. I pushed a fixup, see whether you like it better or not. |
I lost track of this somewhere along the way -- do you want to rebase against current main? |
My impression is that this PR is close to ready, and just needs some rebasing and touching up. |
Sorry been very busy. I'll try to take a look after Christmas. |
Pandoc calls
rsvg-convert
by specifying only a DPI. But that causesrsvg-convert
to try to guess a pixel size as documented in its manpage.Quite often that will result in a very low dpi (much lower than 72).
That is actually a useful diagnostic tool to see when the fallback image is used instead of SVG, but there should be a way to override this from the command-line.
Here is how a document using the
SVG_logo
from pandoc'stest/command
looks like.test.md:
Convert with:
/usr/bin/pandoc --default-image-extension=svg img.md -t docx -o img.docx --trace
This is how it looks like in the free version of Office.com:
LibreOffice 7.6.4.1:
Google Docs:
The PNG produced has only 100x100 pixels (matching the SVG's viewbox):
And the
--dpi
flag ofpandoc
has no effect, you can specify a DPI of 1000 and it'll still produce the exact same image.Solution
Pandoc needs to tell
rsvg-convert
the desired size in the document, at least when it is known in inches or pixels.Add the image attributes to the mediabag to allow access to this information in the fallback conversion code.
Currently this is only done when something like a markdown source is used, I haven't updated all the other readers to extract the image attributes.
It'd be good if it also did this when the image is specified as a percentage of pagesize, but I couldn't figure out how to do the
asks pagewidth
insidePandocMonad
.And now it looks OK everywhere:
Google Docs:
LibreOffice:
Office:
Workarounds:
That will look better, but still have jagged edges everywhere except Office365.
The advantage is that this format doesn't need any PNG fallbacks, and remains an actual vector format.
Still out of all the current options, this is currently (with an unpatched pandoc) the best way I could find to embed vector images.
That will look the best with LibreOffice:
But Google Docs will convert to some unknown DPI when opened and still look bad