Search code examples
imagesvgemacsimagemagickglyph

why does ImageMagick crop this SVG image ... rendering of U+1F382 glyph


UPDATE The SVG image cropping problem has been reduced to ImageMagick. That is, convert birthday_cake.svg birthday_cake.png generates a clipped birthday_cake.png in my particular installation, namely on Ubuntu. I'm currently investigating further.

My version of convert is 6.7.7-10 and I see the latest version is currently at 7.0.7-8 so that might be the issue.

Original Question Follows

I downloaded an SVG file then loaded it into emacs but the bottom third is getting cropped. Also, a slight amount is being cropped from the right side. However, the file is not getting cropped in Firefox nor in Google Chrome. By the way, this SVG is a rendering of the U+1F382 birthday cake Unicode glyph.

SVG image getting cropped when loaded into emacs

I've never noticed this cropping for any SVG or image files before. So I suspect there is some odd interaction between emacs and this particular SVG file.

So what is it about this particular SVG file that is triggering cropping within emacs? Further, how do I instruct emacs to display the entire height and width of this SVG file?

$ wget -q http://www.fileformat.info/info/unicode/char/1f382/birthday_cake.svg
$ emacs-snapshot -Q birthday_cake.svg --geometry 60x24 -eval '(set-frame-name "BAD SVG")'
$ emacs-snapshot --version | head -1
GNU Emacs 25.1.50.2
$ firefox birthday_cake.svg

SVG is included in imagemagick-types:

(member 'SVG (imagemagick-types))
(SVG SVGZ TEXT TGA THUMBNAIL TIFF TIFF64 TILE TIM TTC TTF TXT ...)

Here is an abridged version of the SVG file with the 12KB path shortened for this posting:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
<svg fill-opacity="1" xmlns:xlink="http://www.w3.org/1999/xlink" color-rendering="auto"
     color-interpolation="auto" text-rendering="auto" stroke="black" stroke-linecap="square"
     stroke-miterlimit="10" shape-rendering="auto" stroke-opacity="1" fill="black" stroke-dasharray="none"
     font-weight="normal" stroke-width="1" xmlns="http://www.w3.org/2000/svg" font-family="&apos;Dialog&apos;"
     font-style="normal" stroke-linejoin="miter" font-size="12" stroke-dashoffset="0" image-rendering="auto">
  <!--Unicode Character 'BIRTHDAY CAKE' (U+1F382)-->
  <defs id="genericDefs" />
  <g><g>
    <path d="M285.1875 252 Q285.1875 274.5 ... 118.5469 221.3438 Z" stroke="none" />
  </g></g></svg>

Is some of the attributes in the SVG-tag contributing to this image-cropping? If so, then please itemize those elements and explain the interaction.


Solution

  • You are geting the rendered image through a multipart toolchain. emacs employs ImageMagick for rendering the image, and ImageMagick employs librsvg to convert the vector image to a raster image.

    The error you see is has its root not in the renderer, but in a faulty SVG file. It defines neither width or height attributes nor a viewBox attribute. No inherent width and height for the image can therefore be established. librsvg tries to resolve this by utilizing the combined bounding box of the contained grafical elements to find some substitute values. Unfortunately, it does so with an error.

    To find the bounding box for the content you can load it into the browser and execute

    document.querySelector('svg').getBBox()
    

    on a Javascript console The result is

     {
         x: 11.531200408935547,
         y: 68.4843978881836,
         width: 273.65631103515625,
         height: 272.8125
     }
    

    librsvg gets to the same result insofar as the output image is 273px × 272px, but the content is then not translated such that the left upper border of the box coincides with the left upper border of the image viewport, and so it gets cropped on the right and lower side.

    I don't know how the source webpage, www.fileformat.info, renders this SVG, but you could duplicate their rendering with a viewBox attribute

    viewBox="-50 60 400 400"