mpdf / mpdf

PHP library generating PDF files from UTF-8 encoded HTML
https://mpdf.github.io
GNU General Public License v2.0
4.4k stars 1.07k forks source link

IDs in SVGs parsed case insensitive. #1141

Open AbcAeffchen opened 4 years ago

AbcAeffchen commented 4 years ago

I found this bug

If a svg image is written to the pdf file, all IDs are used case insensitive.

This is mPDF and PHP version and environment (server/fpm/cli etc) I am using

PHP 7.2 / mPDF 8.0.4 on Ubuntu 18.04 LTS

This is a PHP code snippet I use

You can reproduce this with the following code

<?php
$pdf = new Mpdf();
$test = <<<'TAG'
<svg version="1.1" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
    <defs>
        <symbol>
            <g id="eA">
                <rect width="10" height="10" fill="#00F"/>
            </g>
        </symbol>
        <symbol>
            <g id="ea">
                <circle fill="#F00" r="5"/>
            </g>
        </symbol>
    </defs>
    <use x="10" y="10" xlink:href="#ea"></use>
</svg>
TAG;
$pdf->WriteHTML($test);

One would expect to see a red circle but instead a blue square appears in the PDF. If the svg is viewed in a browser one gets the expected result.

In general I could live with using only lower case ids but there are other libraries generating svg images with valid naming schemes that result in such problems.

elminson commented 4 years ago

The issue with this is: when the AdjustHtml is called this part of the code preg_match_all("/(<svg.*?<\/svg>)/si", $html, $svgi); bot all with all the elements but when rendering it does in an invert way (in this case first circle and the square) In order to accomplish what you need you to have to flip the places of the objects.

<?php
$pdf = new Mpdf();
$test = <<<'TAG'
<svg version="1.1" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
    <defs>
        <symbol>
            <g id="ea">
                <circle fill="#F00" r="5"/>
            </g>
        </symbol>
        <symbol>
            <g id="eA">
                <rect width="10" height="10" fill="#00F"/>
            </g>
        </symbol>
    </defs>
    <use x="10" y="10" xlink:href="#ea"></use>
</svg>
TAG;
$pdf->WriteHTML($test);

Another alternative is using two svg with -x and -y


$testa = <<<'TAG'
<svg version="1.1" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
    <defs>
                <symbol>
            <g id="eA">
                <rect width="10" height="10" fill="#00F"/>
            </g>
        </symbol>
    </defs>
    <use x="10" y="10" xlink:href="#eA"></use>
</svg>
<svg version="1.1" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
    <defs>
        <symbol>
            <g id="ea">
                <circle fill="#F00" r="5"/>
            </g>
        </symbol>
    </defs>
    <use x="-10" y="-10" xlink:href="#ea"></use>
</svg>
TAG;
`
AbcAeffchen commented 4 years ago

So what you are saying is, that this isn't a bug in mpdf but I should fix the svg?

In my case the code of the svg file is generated by a library. As a workaround I adjust the svg code but I still consider this a bug in mpdf since the the svg code seems to be perfectly fine.