【问题标题】:adding font to mPDF将字体添加到 mPDF
【发布时间】:2013-07-09 07:31:34
【问题描述】:

当我尝试使用 mPDF 类生成 PDF 时遇到以下错误:

TTF file "C:/wamp/www/inc/mpdf/ttfonts/verdana.ttf": invalid checksum 20f65173c11 table: DSIG (expected 65173c11)

我已将字体文件上传到我的ttfonts 目录并在config_fonts.php 中定义字体,如下所示:

"verdana" => array(
    'R' => "verdana.ttf",
    'B' => "verdanab.ttf",
    'I' => "verdanai.ttf",
    'BI' => "verdanaz.ttf",
    ),

我只在配置设置中打开字体错误报告时看到错误。当我关闭错误报告时,会生成 PDF,但使用的字体不是 Verdana。

知道我做错了什么吗?

【问题讨论】:

标签: php fonts mpdf


【解决方案1】:

无需在屏幕上显示错误。 查看日志文件中的所有错误和警告,例如 php + apache(?) 服务器的“error.log”。 它可以帮助您根据日志文件中的消息找到并解决问题。

无论如何您都应该使用推荐的字体 - 请参阅 mPDF 手册。

您可能需要将 TrueType 字体转换为正确的 MPDF 格式。 (http://mpdf1.com/manual/index.php?tid=409&searchstring=fonts)

【讨论】:

    【解决方案2】:

    除了 lib 文件之外,还有另一种在运行时动态添加字体的“肮脏”方式。这是我的解决方案,因为我无法修改 config_fonts.pdf 文件,因为它位于 vendor/ 文件中,并且会在库更新时被覆盖。

    function add_custom_fonts_to_mpdf($mpdf, $fonts_list) {
        // Logic from line 1146 mpdf.pdf - $this->available_unifonts = array()...       
        foreach ($fonts_list as $f => $fs) {
            // add to fontdata array
            $mpdf->fontdata[$f] = $fs;
    
            // add to available fonts array
            if (isset($fs['R']) && $fs['R']) { $mpdf->available_unifonts[] = $f; }
            if (isset($fs['B']) && $fs['B']) { $mpdf->available_unifonts[] = $f.'B'; }
            if (isset($fs['I']) && $fs['I']) { $mpdf->available_unifonts[] = $f.'I'; }
            if (isset($fs['BI']) && $fs['BI']) { $mpdf->available_unifonts[] = $f.'BI'; }
        }
        $mpdf->default_available_fonts = $mpdf->available_unifonts;
    }
    

    确保提供相对于 mpdf 的 ttfonts/ 目录的字体路径

    重要提示: CSS 字体系列将转换为小写字母 + 无空格,因此“Source Sans Pro-Regular”将变为 sourcesanspro-regular

    例如,我在这里添加了 2 个字体和 3 个字体文件,因为其他字体有常规和粗体版本:

    $mpdf = new mPDF('utf-8', 'A4', '', '', 20, 15, 50, 25, 10, 10);
    $custom_fontdata = array(
        'sourcesanspro-regular' => array(
            'R' => "../../../../wms/hr_frontend/job/internet/fonts/SourceSansPro-Regular/SourceSansPro-Regular.ttf" 
            // use 'R' to support CSS font-weight: normal
            // use 'B', 'I', 'BI' and etc. to support CSS font-weight: bold, font-style: italic, and both...
        ),
        'someotherfont' => array(
            'R' => "../../../../wms/hr_frontend/job/internet/fonts/someotherfont.ttf", // In CSS font-weight: normal
            'B' => "../../../../wms/hr_frontend/job/internet/fonts/someotherfont-bold.ttf" // In CSS font-weight: bold
        )
    );
    add_custom_font_to_mpdf($mpdf, $custom_fontdata);
    $mpdf->WriteHTML($html);
    

    这适用于 mpdf 5.x,但希望它也适用于 6.x。有人试过吗?

    【讨论】:

    • 我可以确认这适用于 mPDF 的 6.x 分支。感谢您提出这个建议,我不知道为什么所有这些逻辑都被纳入 mpdf 的初始设置并且不能在它之外重新运行ಠ_ಠ它会解决很多字体问题! :)
    【解决方案3】:

    以下是在 mpdf 库中添加新字体系列的步骤:

    1. 下载字体zip并解压。
    2. 将新的newFont.ttf 字体文件添加到此位置的/mpdf/ttfonts 文件夹。
    3. 编辑 /mpdf/config_fonts.php/mpdf/src/config/FontVariables.php 以将条目添加到新字体文件的 $this->fontdata 数组中。喜欢:

      $this->fontdata = array(
          "newFont" => array(
          'R' => "newFont-Regular.ttf",
          'B' => "newFont-Bold.ttf",
          'I' => "newFont-Italic.ttf",
          'BI' => "newFont-BoldItalic.ttf",
      ),
      
    4. font-family: 'newFont'; 现在在样式表中可用。

    5. $mpdfObj = new mPDF('', '', 'newFont'); $mpdfObj->SetFont('newFont');

    6. 现在您的新字体已添加。

    【讨论】:

    【解决方案4】:

    基于@hrvoje-golcic 的回答,这是一种改进且不那么脏的方法,无需编辑config_fonts.php 即可将字体添加到mPDF。我正在使用 Laravel,我使用 composer 安装了 mPDF。

    1. 按照作者的建议,在初始化mPDF 之前定义一个名为_MPDF_TTFONTPATH 的常量,并将值作为ttfonts 文件夹的路径(该常量至少从5.3 开始就存在)。
    2. vendor/mpdf/mpdf/ttfonts 文件夹复制到您控制的位置(供应商文件夹之外)。
    3. 将您的自定义字体与其他字体一起添加到该文件夹​​中。
    4. 将您的配置添加到mPDF 实例的fontdata 属性中。

    注意ttfonts 文件夹大约有 90MB,因此可能还有更好的方法,但是您必须复制所有字体,因为原始配置添加了它们。请参阅此答案底部的作曲家脚本替代方案。

    重要提示:CSS font-family will be transformed 转为小写字母 + 无空格,因此“Source Sans Pro”将变为 sourcesanspro。

    这是一个例子:

    if (!defined('_MPDF_TTFONTPATH')) {
        // an absolute path is preferred, trailing slash required:
        define('_MPDF_TTFONTPATH', realpath('fonts/'));
        // example using Laravel's resource_path function:
        // define('_MPDF_TTFONTPATH', resource_path('fonts/'));
    }
    
    function add_custom_fonts_to_mpdf($mpdf, $fonts_list) {
    
        $fontdata = [
            'sourcesanspro' => [
                'R' => 'SourceSansPro-Regular.ttf',
                'B' => 'SourceSansPro-Bold.ttf',
            ],
        ];
    
        foreach ($fontdata as $f => $fs) {
            // add to fontdata array
            $mpdf->fontdata[$f] = $fs;
    
            // add to available fonts array
            foreach (['R', 'B', 'I', 'BI'] as $style) {
                if (isset($fs[$style]) && $fs[$style]) {
                    // warning: no suffix for regular style! hours wasted: 2
                    $mpdf->available_unifonts[] = $f . trim($style, 'R');
                }
            }
    
        }
    
        $mpdf->default_available_fonts = $mpdf->available_unifonts;
    }
    
    $mpdf = new mPDF('UTF-8', 'A4');
    add_custom_fonts_to_mpdf($mpdf);
    $mpdf->WriteHTML($html);
    

    Composer 安装后脚本

    无需复制所有字体并将它们添加到 git,使用 composer 安装后脚本的便捷解决方法可以为您做到这一点。

    首先,确保要复制字体的文件夹存在,并在其中创建.gitignore,内容如下:

    *
    !.gitignore
    !SourceSansPro-Regular.ttf
    !SourceSansPro-Bold.ttf
    

    这将忽略除.gitignore 文件和您要添加的字体之外的所有内容。

    接下来,将以下脚本添加到您的 composer.json 文件中:

    "scripts": {
        "post-install-cmd": [
            "cp -f vendor/mpdf/mpdf/ttfonts/* resources/fonts/"
        ],
        "post-update-cmd": [
            "cp -f vendor/mpdf/mpdf/ttfonts/* resources/fonts/"
        ]
    }
    

    注意事项

    经过测试,它可以与 6.1 一起使用。
    在 7.x 中,作者implemented 一种优雅的方式添加外部字体。

    【讨论】:

    • 这可能是添加自定义字体的正确方法,但是...如果您使用的是 Laravel 和 mPDF 7.x,这里提到了最简单的方法adding custom fonts in mPDF 7.x跨度>
    • 那么问题是手动更改vendor文件夹中的东西是非常错误的
    • 啊啊太有趣了,我在文档中的任何地方都找不到小写转换。他们为什么这样做,为什么不在自定义字体部分用一个大红巨星巨大的闪烁免责声明来记录它?谢谢@s3v3n。
    【解决方案5】:

    Mpdf 添加 Arial 字体

    1. 下载字体文件:https://github.com/JotJunior/PHP-Boleto-ZF2/blob/master/public/assets/fonts/arial.ttf

    2. 将 arial.ttf 粘贴到 mpdf/ttfonts

    3. 用 fontdata 数组打开 config_fonts.php 和下面的代码

      "arial" => 数组( 'R' => "arial.ttf", ),

    【讨论】:

      【解决方案6】:

      只需将字体添加到 FontVariable.php

                      "pacifico" => [
                      'R' => "Pacifico.ttf",
                      'useOTL' => 0xFF,
                      'useKashida' => 75,
                  ],
      

      确保 ttf 文件名是否以大写字母开头,例如 Pacifico.ttf,然后像我在顶部一样以小写字母开头命名字体系列。 例如制作这个pacifico 现在只需通过创建测试 php 文件来测试它

      require_once __DIR__ . '/autoload.php';
      $defaultConfig = (new Mpdf\Config\ConfigVariables())->getDefaults();
      $fontDirs = $defaultConfig['fontDir'];
      $defaultFontConfig = (new Mpdf\Config\FontVariables())->getDefaults();
      $fontData = $defaultFontConfig['fontdata'];
      $mpdf = new \Mpdf\Mpdf([
      'mode' => 'utf-8',
      'format' => 'A4'.('orientation' == 'L' ? '-L' : ''),
      'orientation' => 0,
      'margin_left' => 3,
      'margin_right' => 3,
      'margin_top' => 3,
      'margin_bottom' => 0,
      'margin_header' => 0,
      'margin_footer' => 0,
      ]);    
      $texttt= '
          <html>
          <p style="font-family: dejavusanscondensed;"> Text in Frutiger </p>
          <p style="font-family: freeserif;"> Text in Frutiger </p>
          <p style="font-family: freemono;"> Text in Frutiger </p>
          <p style="font-family: freeserif;"> مرحبا بالعالم </p>
          <p style="font-family: unbatang;"> 하는 바에 의하여 영장제도 </p>
          <p style="font-family: centurygothic;"> Text in Frutiger </p>
          <p style="font-family: pacifico;"> Text in Frutiger </p>
          <p style="font-family: windsong;"> Text in Frutiger </p>
          </html>';
           $mpdf->WriteHTML($texttt,\Mpdf\HTMLParserMode::HTML_BODY);
      $mpdf->Output();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-21
        • 1970-01-01
        • 1970-01-01
        • 2015-08-21
        • 2018-05-23
        • 1970-01-01
        • 2022-01-18
        相关资源
        最近更新 更多