Menu

Support for CSS Styling in SVG while adding the file to PDF

Help
maxcode360
2014-12-09
2014-12-11
  • maxcode360

    maxcode360 - 2014-12-09

    Hi !

    I have a SVG file showing the letter 'A' in Orbitron font( in ttf format).

    When I open this SVG file in any of the browsers(Chrome,FireFox,IE,Opera latest versions) it works fine.

    But when I add this SVG file to a PDF file(via TCPDF ImageSVG() function) the SVG is imported successfully and the letter 'A' is shown in the PDF but the Font is not displayed correctly.

    Instead the PDF file is rendered using the default 'Helvetica' font, even when the SVG file has different font specification.

    The Problem: The SVG file includes a CSS stylesheet which defines a @font-face with the 'font-family' and 'src'.The src includes a url to the ttf font.

    I understand from previous experience this will happen since I have not added the custom Font via code(i know it works that way but that is not the requirement here) , since I am importing the SVG file (not creating it) TCPDF should use the styling information provided in the SVG while importing, atleast for the TTF fonts since its a supported format.

    Resources for clarity :

    (input)SVG File with CSS defining/linking the font : https://www.dropbox.com/s/c2ua1e6f7cgg8qw/test4.svg?dl=0

    (output)PDF File created from TCPDF : https://www.dropbox.com/s/juch4fonpat494r/test.pdf?dl=0

    Code for Testing : https://www.dropbox.com/s/245dklpjyxe7uhm/SVGConvertProject.zip?dl=0

    current output: https://www.dropbox.com/s/qj0q43ngq765hbd/current_output.png?dl=0

    expected output: https://www.dropbox.com/s/uoe23bbzh70b1k0/expected%20output.png?dl=0

     
  • cpw

    cpw - 2014-12-11

    this will happen since I have not added the custom Font via code(i know it works that way but that is not the requirement here)

    Well, exactly that is the problem.

    TCPDF should use the styling information provided in the SVG while importing, atleast for the TTF fonts since its a supported format.

    You can implement that quite easily yourself by doing something like this:

    require('./tcpdf/tcpdf.php');
    
    $pdf = new TCPDF($orientation = "P", $unit = "mm", $format = "A4", $unicode = true, $encoding = 'UTF-8', $diskcache = false, $pdfa = false);
    
    // open SVG file (might need allow_url_fopen set and a wrapper if the file isn't on the server)
    $svgFileHandle = fopen("test4.svg", "r");
    
    $fontFileURL = false;
    $fontFamily = false;
    
    // read every line
    while (!feof($svgFileHandle))
    {
        $line = fgets($svgFileHandle);
    
        // This search for the URL and the font family is "quick & dirty"
        // and works for your specific file just as an example, but you
        // might want to check if this always works as expected. There
        // are surely better, safer ways to do this (e.g. using regular
        // expressions). Also you'll need to alter this if there's more
        // than one font.
    
        if(strpos($line, "font-family:") !== false)
        {
            $fontFamily = substr($line, strpos($line, "font-family: '")+14, -4);
        }
    
        if(strpos($line, "format('truetype')") !== false)
        {
            $fontFileURL = substr($line, strpos($line, "src:url('")+9, -24);
            break;
        }
    }
    
    fclose($svgFileHandle);
    
    if($fontFileURL === false)
    {
        die("No URL found.");
    }
    
    if($fontFamily === false)
    {
        die("Font family not found.");
    }
    
    // Check if this font already exists
    if(!file_exists("./tcpdf/fonts/".$fontFamily."php"))
    {
        // Directly importing $fontFileURL (http://mytestingsite.esy.es/wp-content/fontserve.php)
        // won't work (oddly without any error whatsoever), probably because it's a PHP file returning
        // a font. So we'll download it to a temporary directory:
    
        // Again: might need allow_url_fopen set and a wrapper if the file isn't stored locally
        $ttfHandleRemote = fopen($fontFileURL, "r");
    
        $ttfHandleLocal = fopen("./fonttmp/".$fontFamily.".ttf", "w+");
    
        while (!feof($ttfHandleRemote))
        {
            $line = fgets($ttfHandleRemote);
            fwrite($ttfHandleLocal, $line);
        }
    
        fclose($ttfHandleRemote);
        fclose($ttfHandleLocal);
    
        // Convert/add font
        $pdf->addTTFfont("./fonttmp/".$fontFamily.".ttf");
    
        // Delete temporary download
        unlink("./fonttmp/".$fontFamily.".ttf");
    }
    
    $pdf->AddFont($fontFamily);
    
    $pdf->AddPage();
    $pdf->ImageSVG('test4.svg');
    
    $pdf->Output();
    

    In this special case it does however not work - the problem doesn't seem to be in my script, but in the "Orbitron" font, the font itself won't work for some reason. I tried downloading it from your URL as well as from http://www.1001freefonts.com/orbitron.font and tried the following (no SVG or anything involved):

    require('./tcpdf/tcpdf.php');
    
    $pdf = new TCPDF($orientation = "P", $unit = "mm", $format = "A4", $unicode = true, $encoding = 'UTF-8', $diskcache = false, $pdfa = false);
    
    $pdf->addTTFfont("./fonttmp/orbitron.ttf");
    
    $pdf->AddFont("orbitron");
    
    $pdf->AddPage();
    
    $pdf->setFont("orbitron");
    $pdf->MultiCell($w=0, $h=0, "Some text");
    
    $pdf->Output();
    

    It'll use Helvetica. If I use a different font (just replacing "orbitron.ttf" with e.g. "frutiger65.ttf" and "orbitron" with "frutiger65" it'll work.

    Also the following will work and show the "A" in Free Serif:

    require('./tcpdf/tcpdf.php');
    
    $pdf = new TCPDF($orientation = "P", $unit = "mm", $format = "A4", $unicode = true, $encoding = 'UTF-8', $diskcache = false, $pdfa = false);
    
    $pdf->AddFont("orbitron", "", "./tcpdf/fonts/freeserif.php");
    
    $pdf->AddPage();
    
    $pdf->ImageSVG('test4.svg');
    
    $pdf->Output();
    

    So basically my workaround should do the trick, the only problem here seems to be the font itself.

    BTW: Be careful with serving fonts openly available to everyone. Orbitron won't be a problem, because as far as I know it's licensed under the Open Font License and may be freely distributed, just be careful with commercially licensed fonts.

     

Log in to post a comment.