bithost-gmbh / pdfviewhelpers

TYPO3 CMS extension that provides various Fluid ViewHelpers to generate PDF documents.
GNU General Public License v3.0
44 stars 20 forks source link

Font file path is not configured correctly for tcpdf #137

Closed liayn closed 4 years ago

liayn commented 4 years ago

\TCPDF_FONTS::_getfontpath assumes the font path to be set via K_PATH_FONTS or falls back to the location of the TCPDF libarary location.

BasePDF class must set this constant accordingly.

The function is used indirectly within \TCPDF::AddFont.

The big problem is that you can't use custom fonts together with default fonts as this constant can only hold 1 path.

maechler commented 4 years ago

I think I did not yet understand the issue, but I try to explain what I believe is the current behaviour.

The path plugin.tx_pdfviewhelpers.settings.fonts.outputPath specifies where automatically generated font files from TCPDF will be stored. This is only true for custom fonts, fonts that are shipped with TCPDF reside within Resources/Private/PHP/tcpdf/fonts (= K_PATH_FONTS by default).

So TCPDF will find its own fonts, as we do not overwrite K_PATH_FONTS. For custom fonts we store the font paths with $this->customFontFilePaths[$fontName] = $fontFilePath; and overwrite the font file path in SetFont whenever such a custom font is used.

https://github.com/bithost-gmbh/pdfviewhelpers/blob/32c6bcd0e73159176b49e4be46c4e4712ec47a18/Classes/Model/BasePDF.php#L293-L314

Does our approach with overwriting the font file path in SetFont not work all the time? Or is there another issue?

schugabe commented 4 years ago

We have a class CustomPdf that extends \Bithost\Pdfviewhelpers\Model\BasePDF and added two custom fonts:

plugin.tx_pdfviewhelpers.settings {
  config {
    class = CustomPdf
    fonts {
      addTTFFont {
        univers {
          path = path/univers.ttf
        }
        universbold {
          path = path/univers-bold.ttf
        }
      }
    }
  }
}

In the CustomPdf we create a header:

public function basePdfHeader() {
  $this->SetFont('univers');
  $slogan = '<div style="font-weight:bold;">Bold</div>';
  $this->writeHTMLCell(0, 0, 31.5, $this->y, $slogan, 0, 0, false, true, 'L', true);
}

The writeHTMLCell tries to load the bold variant of the font but cannot find it since it searches in the K_PATH_FONTS path and not the custom path. This was working in version 2.1.0 and if you change the font path back to the folder in the extension it also works again.

If we add the bold font $this->SetFont('universb'); before also calling $this->SetFont('univers'); the bold font is already loaded and the problem does not show up.

Maybe the solution would be to call SetFont for all custom fonts.

maechler commented 4 years ago

I see, there is an issue with writeHTML. So as a workaround you could probably set plugin.tx_pdfviewhelpers.settings.fonts.outputPath = EXT:pdfviewhelpers/Resources/Private/PHP/tcpdf/fonts.

After a short analysis I think we would have to add the following to BasePDF (see https://github.com/bithost-gmbh/pdfviewhelpers/commit/4672e17dcca188a6b4e5d5194fd43317ed42ff67):

    /**
     * Overwrite AddFont in order to automatically provide paths to custom fonts
     *
     * @inheritdoc
     */
    public function AddFont($family, $style='', $fontfile='', $subset='default')
    {
        if (empty($fontfile) && isset($this->customFontFilePaths[$family])) {
            $fontfile = $this->customFontFilePaths[$family];
        }

        return parent::AddFont($family, $style, $fontfile, $subset);
    }

    /**
     * @param $fontName
     * @param $fontFilePath
     */
    public function addCustomFontFilePath($fontName, $fontFilePath)
    {
        $this->fontlist[] = $fontName;
        $this->customFontFilePaths[$fontName] = $fontFilePath;
    }

In order to make it work with the HTML ViewHelper. Can you verify whether this solves your issue?

maechler commented 4 years ago

BTW..maybe it would be more convenient to use the HeaderViewHelper :)

<pdf:header>
    <pdf:html>
        <div style="font-weight:bold; font-style: univers;">Bold</div>
    </pdf:html>
</pdf:header>
liayn commented 4 years ago

BTW..maybe it would be more convenient to use the HeaderViewHelper :)

<pdf:header>
    <pdf:html>
        <div style="font-weight:bold; font-style: univers;">Bold</div>
    </pdf:html>
</pdf:header>

Unless you have a bit more stuff going on than what is posted above. :)

schugabe commented 4 years ago

I see, there is an issue with writeHTML. So as a workaround you could probably set plugin.tx_pdfviewhelpers.settings.fonts.outputPath = EXT:pdfviewhelpers/Resources/Private/PHP/tcpdf/fonts.

After a short analysis I think we would have to add the following to BasePDF (see 4672e17):

    /**
     * Overwrite AddFont in order to automatically provide paths to custom fonts
     *
     * @inheritdoc
     */
    public function AddFont($family, $style='', $fontfile='', $subset='default')
    {
        if (empty($fontfile) && isset($this->customFontFilePaths[$family])) {
            $fontfile = $this->customFontFilePaths[$family];
        }

        return parent::AddFont($family, $style, $fontfile, $subset);
    }

    /**
     * @param $fontName
     * @param $fontFilePath
     */
    public function addCustomFontFilePath($fontName, $fontFilePath)
    {
        $this->fontlist[] = $fontName;
        $this->customFontFilePaths[$fontName] = $fontFilePath;
    }

In order to make it work with the HTML ViewHelper. Can you verify whether this solves your issue?

I added the suggested fix and it prevents the exception :+1:

maechler commented 4 years ago

Unless you have a bit more stuff going on than what is posted above. :)

That's true of course :)

maechler commented 4 years ago

I added the suggested fix and it prevents the exception 👍

Perfect, thanks for reporting and testing! I will create a new release today.

maechler commented 4 years ago

I just released v2.2.1 which includes the fix mentioned.