lovell / sharp

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
https://sharp.pixelplumbing.com
Apache License 2.0
29.25k stars 1.3k forks source link

SVG text-decoration not inherited by nested tspan element #3240

Open themachho opened 2 years ago

themachho commented 2 years ago

Possible bug

Is this a possible bug in a feature of sharp, unrelated to installation?

If you cannot confirm both of these, please open an installation issue instead.

Are you using the latest version of sharp?

If you cannot confirm this, please upgrade to the latest version and try again before opening an issue.

If you are using another package which depends on a version of sharp that is not the latest, please open an issue against that package instead.

What is the output of running npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp?

System: OS: Windows 10 10.0.19044 CPU: (8) x64 Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz Memory: 1.49 GB / 15.86 GB

Binaries: Node: 16.13.0 - C:\Program Files\nodejs\node.EXE npm: 8.1.3 - C:\Program Files\nodejs\npm.CMD

npmPackages: sharp: ^0.30.5 => 0.30.5

What are the steps to reproduce?

Sharp is not adding text-decoration underline to the converted image.

What is the expected behaviour?

The text is underlined.

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem

This is a simple function to convert an SVG (encoded in base64) to png and return the converted image. Is part of an NodeJS/ExpressJS API. It receives the buffer, returns a bitmap.

async convertSVG(svgData) {
  let buffer = Buffer.from(svgData, "base64");

  const sharp = require("sharp");
  let tempFileName = path.join("temp.png");

  await sharp(Buffer.from(buffer, "utf-8"), {
    density: 300,
  })
    .png()
    .toFile(tempFileName)
    .then(() => {})
    .catch((err) => {
      // Logger.error(err);
      return [400, "Could not convert SVG"];
    });

  buffer = fs.readFileSync(tempFileName);

  const rimraf = require("rimraf");
  rimraf(tempFileName, () => {}); // Remove temp file

  return [200, buffer.toString("base64")];
}

This is the SVG, created with FabricJS and exported with canvas.toSVG();, but its not related to FabricJS

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="500" height="500" viewBox="0 0 500 500" xml:space="preserve">
<desc>Created with Fabric.js 5.1.0</desc>
<defs>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="white"></rect>
<g transform="matrix(1.03 0 0 1.11 210.5 135.5)" style="" id="e2d7k"  >
        <rect fill="#FFFFFF" x="-146.02" y="-40.68" width="292.04" height="81.36"></rect>
        <text xml:space="preserve" font-family="Arial" font-size="72" font-style="normal" text-decoration="underline" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(70,68,69); fill-rule: nonzero; opacity: 1; white-space: pre;" ><tspan x="-146.02" y="22.62" >ABCDEF</tspan></text>
</g>
</svg>

Please provide sample image(s) that help explain this problem

This is the output of www.svgviewer.dev, as you can see, the text is underlined. svgviewer-png-output

This is the output from sharp, the text is not underlined descarga

Looks like text-decoration="underline" is not being processed. Same issue if the text-decoration property is removed and is added inside style="text-decoration:underline; etc etc

lovell commented 2 years ago

This is an SVG spec vs implementation thing, please see https://gitlab.gnome.org/GNOME/librsvg/-/issues/99

You'll need to add the text-decoration attribute to the tspan element.

themachho commented 2 years ago

Parsed the DOM and inherited the text-decoration to the tspan and now it is rendered correctly. The issue can be closed now. Thanks!