yWorks / svg2pdf.js

A javascript-only SVG to PDF conversion utility that runs in the browser. Brought to you by yWorks - the diagramming experts
MIT License
649 stars 98 forks source link

SVG with data:image/png;base64 pattern and bold font (numeric) #173

Closed nowrap closed 3 years ago

nowrap commented 3 years ago

Hello, i am trying to convert a generated SVG to PDF. I looks fine as SVG in chrome: `

<path fill="#dcdcdc" d="M0 0h240.94v153.07H0z"/>
<text transform="translate(75.46 14.56)" font-size="9" fill="#1d1d1b" font-family="Arial-BoldMT,Arial" font-weight="700">Fremdfirmenausweis</text>
<text transform="translate(99.21 43.72)" font-size="8" fill="#1d1d1b" font-family="ArialMT,Arial">Vorname</text>
<text transform="translate(99.21 69.23)" font-size="8" fill="#1d1d1b" font-family="ArialMT,Arial">Nachname</text>
<text transform="translate(99.21 94.74)" font-size="8" fill="#1d1d1b" font-family="ArialMT,Arial">Firma</text>
<text transform="translate(99.21 124.5)" font-size="8" fill="#1d1d1b" font-family="ArialMT,Arial">Unterweisung von:</text>
<text transform="translate(99.21 142.93)" font-size="8" fill="#1d1d1b" font-family="ArialMT,Arial">Gültig bis:</text>
<rect x="99.21" y="45.35" width="136.06" height="14.17" rx="2.83" fill="#fff" stroke="#1d1d1b" stroke-miterlimit="10" stroke-width=".5"/>
<rect x="99.21" y="70.87" width="136.06" height="14.17" rx="2.83" fill="#fff" stroke="#1d1d1b" stroke-miterlimit="10" stroke-width=".5"/>
<rect x="99.21" y="96.38" width="136.06" height="14.17" rx="2.83" fill="#fff" stroke="#1d1d1b" stroke-miterlimit="10" stroke-width=".5"/>
<rect x="184.25" y="114.8" width="51.02" height="14.17" rx="2.83" fill="#fff" stroke="#1d1d1b" stroke-miterlimit="10" stroke-width=".5"/>
<rect x="184.25" y="133.23" width="51.02" height="14.17" rx="2.83" fill="#fff" stroke="#1d1d1b" stroke-miterlimit="10" stroke-width=".5"/>
<rect id="ci-id-box" x="14.17" y="121.89" width="70.87" height="14.17" rx="2.83" fill="#fff" stroke="#1d1d1b" stroke-miterlimit="10" stroke-width=".5"/>
<text id="ci-fn" transform="translate(101.21 55.66)" font-size="9" fill="#1d1d1b" font-family="ArialMT,Arial">TestV</text>
<text id="ci-ln" transform="translate(101.21 81.17)" font-size="9" fill="#1d1d1b" font-family="ArialMT,Arial">TestN</text>
<text id="ci-co" transform="translate(101.21 106.69)" font-size="9" fill="#1d1d1b" font-family="ArialMT,Arial">Test-Firma</text>
<text id="ci-fr" transform="translate(209.76 125.11)" text-anchor="middle" font-size="9" fill="#1d1d1b" font-family="ArialMT,Arial">13.02.2021</text>
<text id="ci-to" transform="translate(209.76 143.54)" text-anchor="middle" font-size="9" fill="#1d1d1b" font-family="ArialMT,Arial">13.02.2022</text>
<text id="ci-id" transform="translate(49.61 132.2)" text-anchor="middle" font-size="9" fill="#1d1d1b" font-family="ArialMT,Arial">12345678</text>
<rect x="5.67" y="19.84" width="87.87" height="90.71" rx="2.83" fill="url(#ci-a)" stroke="#1d1d1b" stroke-miterlimit="10" stroke-width=".5"/>

`

But the left path with the image isn't rendered to the pdf. And the headline with font-weigth isn't really bold in the pdf.

Maybe someone can put some light on this issue ;)

Regards nowrap

PS I tried the posted svg src in the latest Svg2pdf Playground today

nowrap commented 3 years ago

Ok, #128 says font-weigths only in prosa. So font-weight="bold" works

HackbrettXXX commented 3 years ago

See my comment on #128. A pull request would be very welcome. I'm closing this as duplicate of #128.

nowrap commented 3 years ago

Thanks for reviewing the issue. The font-weight was the minor part. What about the image pattern?

HackbrettXXX commented 3 years ago

Ah sorry, didn't read that part, so much text :D I will have a look at this tomorrow.

nowrap commented 3 years ago

Thx alot! And sorry for the amount of text (mainly the image pattern source). If i can provide any help, please let me know.

yGuy commented 3 years ago

This can be simplified, of course - unfortunately the playground strips away the image...

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500px" height="500px" viewBox="0 0 100 100"> 
  <defs> 
    <pattern id="img" height="100%" width="100%" patternContentUnits="objectBoundingBox"> 
        <image height="1" width="1" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" /> 
    </pattern> 
  </defs> 
  <rect x="5" y="5" width="90" height="90" fill="url(#img)" stroke="black"/>
</svg>
HackbrettXXX commented 3 years ago

I cannot reproduce the issue with either of the samples outside the playground. @nowrap could you share a complete repro including the JavaScript code?

nowrap commented 3 years ago

Moin, i just put my svg code into the svg2pdf playground: http://raw.githack.com/yWorks/svg2pdf.js/master/

The svg should look like this: https://www.nowrap.net/github/nowrap.svg

But the playground "ignores" the image pattern (screenshot): https://www.nowrap.net/github/nowrap.png

The same happens with the simplified version from @yGuy https://www.nowrap.net/github/yguy.svg https://www.nowrap.net/github/yguy.png

Playground Link with yGuy SVG: http://raw.githack.com/yWorks/svg2pdf.js/master/?svg=%253Csvg%2520viewBox%253D%25220%25200%2520100%2520100%2522%2520height%253D%2522500px%2522%2520width%253D%2522500px%2522%2520xmlns%253Axlink%253D%2522http%253A%252F%252Fwww.w3.org%252F1999%252Fxlink%2522%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%2520%250A%2520%2520%253Cdefs%253E%2520%250A%2509%253Cpattern%2520patternContentUnits%253D%2522objectBoundingBox%2522%2520width%253D%2522100%2525%2522%2520height%253D%2522100%2525%2522%2520id%253D%2522img%2522%253E%2520%250A%2520%2520%2520%2520%2509%2520%250A%2520%2520%2509%253C%252Fpattern%253E%2520%250A%2520%2520%253C%252Fdefs%253E%2520%250A%2520%2520%253Crect%2520stroke%253D%2522black%2522%2520fill%253D%2522url%28%2523img%29%2522%2520height%253D%252290%2522%2520width%253D%252290%2522%2520y%253D%25225%2522%2520x%253D%25225%2522%253E%253C%252Frect%253E%250A%253C%252Fsvg%253E

i can try to make a sample project with both svgs

Regards nowrap

yGuy commented 3 years ago

The playground will remove image tags for privacy/security reasons, as I indicated, already. Hence the playground is not helpful in diagnosing. You can use the playground locally and remove /disable the DOMSanitizer.

nowrap commented 3 years ago

Ok, you are right @yGuy the playground removes all nodes with xlink:href or href attributes: https://github.com/yWorks/svg2pdf.js/blob/master/playground/index.js

I created a demo with our two SVGs and it works! https://www.nowrap.net/github/

It uses the newest versions of jspdf and svg2pdf

nowrap commented 3 years ago

Sorry for chasing a phantom ;(

HackbrettXXX commented 3 years ago

No problem. We should probably improve the playground in this regard,

szykuc commented 3 years ago

Hello, @nowrap when i try use your code with little modification to save result as pdf file i get blank document.

pdf.svg(svgElement, { width, height }) .then( () => document.getElementById('pdf-iframe').setAttribute('src', pdf.output('datauristring')), pdf.save('myPDF.pdf') );

@HackbrettXXX I have a svg file with multiple data:image/png;base64 which I try save to pdf file: https://github.com/szykuc/svg/blob/main/unit.svg

  1. Why I get only vector paths in my pdf file? Is svg2pdf ignore 'use' tags?
  2. Can ignore some of tags to render in pdf? For example tags with certain class 'unit-acc'
HackbrettXXX commented 3 years ago

@szykuc

  1. You can call output (or save, which calls output) only once per document.
  2. svg2pdf does not ignore use tags. However, the playground removes some elements and attributes from the SVG because of security reasons
  3. Just add a style rule to the SVG for the respective classes like display: none or visibility: hidden