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

SVG Paths dropped due to low DPI during image draw #502

Closed
malthe opened this issue Sep 8, 2017 · 3 comments
Closed

SVG Paths dropped due to low DPI during image draw #502

malthe opened this issue Sep 8, 2017 · 3 comments

Comments

@malthe
Copy link

malthe commented Sep 8, 2017

I have an SVG path that seems to be dropped or discarded from PDF output due to the DPI setting of 96 in weasyprint/images.py:draw(...). If I reduce the DPI even lower, predictably even more paths are discarded from output.

This seems somewhat logical but it's unfortunate that the DPI setting is not configurable.

But now, for a mystery. If I put an import pdb; pdb.set_trace() like so:

    def draw(self, context, concrete_width, concrete_height, _image_rendering):
        try:
            svg = ScaledSVGSurface(
                cairosvg.parser.Tree(
                    bytestring=self._svg_data, url=self._base_url,
                    url_fetcher=self._cairosvg_url_fetcher),
                output=None, dpi=96, parent_width=concrete_width,
                parent_height=concrete_height)
            if svg.width and svg.height:
                context.scale(
                    concrete_width / svg.width, concrete_height / svg.height)
                context.set_source_surface(svg.cairo)
 
                # sic !!!
                import pdb; pdb.set_trace()

                context.paint()
        except Exception as e:
            LOGGER.error(
                'Failed to draw an SVG image at %s : %s', self._base_url, e)

In this case, the DPI setting seems to be ignored and no paths are discarded at all, no matter the DPI setting.

I have not been able to get any further in understanding this behavior.

@liZe
Copy link
Member

liZe commented Sep 8, 2017

It's proably a duplicate of #278 / #339 / #431 / #438… Short answer: it's a bug in cairo fixed upstream since April 2016, but no stable version has the patch. You can use the unstable 1.15.6 version for example.

@malthe
Copy link
Author

malthe commented Sep 8, 2017

OK thanks!

I ended up simply patching the DPI parameter:

def replace_tuple_value(t, value, new_value):
    l = list(t)
    i = l.index(value)
    assert i >= 0
    l[i] = new_value
    return tuple(l)


# Monkey-patch DPI setting to 300, see
# https://github.com/Kozea/WeasyPrint/issues/502.
from weasyprint.images import SVGImage
func = SVGImage.draw.im_func
fn_code = func.func_code
func.func_code = types.CodeType(
    fn_code.co_argcount,
    fn_code.co_nlocals,
    fn_code.co_stacksize,
    fn_code.co_flags,
    fn_code.co_code,
    replace_tuple_value(fn_code.co_consts, 96, 300),
    fn_code.co_names,
    fn_code.co_varnames,
    fn_code.co_filename,
    fn_code.co_name,
    fn_code.co_firstlineno,
    fn_code.co_lnotab,
    fn_code.co_freevars,
    fn_code.co_cellvars
)

Works for me but YMMV :-)

@liZe
Copy link
Member

liZe commented Sep 8, 2017

Thanks, may help other users too!

@liZe liZe closed this as completed Sep 8, 2017
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

2 participants