【问题标题】:Embedding SVGs into PDFs with embedded fonts将 SVG 嵌入到带有嵌入字体的 PDF 中
【发布时间】:2017-08-13 22:56:22
【问题描述】:

我想将 SVG 图像嵌入 PDF,并使用正确的字体呈现 SVG text 元素中指定的字体系列。

我使用的字体是'Lato' TTF fonts

这是我用来将字体转换为 TCPDF 的“原生格式”的代码:

$variants = [
    'Black',
    'BlackItalic',
    'Bold',
    'BoldItalic',
    'Hairline',
    'HairlineItalic',
    'Heavy',
    'HeavyItalic',
    'Italic',
    'Light',
    'LightItalic',
    'Medium',
    'MediumItalic',
    'Regular',
    'Semibold',
    'SemiboldItalic',
    'Thin',
    'ThinItalic',
];

foreach ($variants as $variant) {
    \TCPDF_FONTS::addTTFfont(
        '/var/www/fonts/Lato-' . $variant . '.ttf',
        '',
        '',
        32,
        '/var/www/fonts/output/'
    );
}

这是我用来生成带有嵌入式 SVG 的测试 PDF 的代码:

$svg_content = '<svg width="600px" height="800px">';
foreach ($variants as $key => $variant) {
    $svg_content .= '<text x="30" y="' . ( 30 * ( $key + 1 ) ) . '" fill="#ED6E46" font-size="20" font-family="\'Lato-' . $variant . '\'" text-anchor="start">The quick brown fox jumped over the lazy dog (' . $variant . ').</text>';
}
$svg_content .= '</svg>';

$pdf = new TCPDF();

$pdf->SetPrintHeader(false);
$pdf->SetPrintFooter(false);
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->SetMargins(0, 0, -1, true);
$pdf->SetAutoPageBreak(false, 0);

$pdf->AddPage();

$pdf->AddFont('Lato-Black', '', '/var/www/fonts/output/latoblack.php');

$pdf->ImageSVG('@' . $svg_content, 0, 0, 300, 300, '', $align='', $palign='C', $border=0, false);

$pdf->Output(
    preg_replace('/[^A-Za-z0-9]/', '', $influencer->getName()) . '.pdf',
    'I'
);

我得到的结果是所有文本都以我认为是 Helvetica 的方式呈现:

如果我在调用 ImageSVG() 之前添加一行,如下所示:

$pdf->SetFont('Lato-Black', '', null, '/var/www/fonts/output/latoblack.php');

然后所有的文本都用 Lato-Black 渲染:

在我看来,字体可以很好地嵌入 PDF,但 SetFont 显然为后续 PDF 文本元素设置了当前字体,而 SVG 图像中的 text 元素使用此字体呈现。

我希望的行为是在 PDF 中尊重 SVG text 元素上定义的 font-family 属性,以便每一行使用行尾括号中提到的字体变体呈现。

我该怎么做?

【问题讨论】:

  • 仅仅因为该文件被称为“Lato-BoldItalic”,并不意味着您应该在 SVG 中引用它。您是否尝试过仅使用font-family="Lato"?如果这如我所怀疑的那样有效,那么您可以使用 CSS 中的正常方式生成所有变体 - font-weightfont-style
  • 是的,我试过了。它似乎没有任何区别 - 只有当我在 SVG 上下文之外调用 TCPDF SetFont() 方法时,字体才会发生变化。我想知道我是否在某个地方遗漏了一步。

标签: pdf svg fonts pdf-generation tcpdf


【解决方案1】:

您可以从以下代码开始,然后向后合并您的更改。

需要明确的是,我并不是特别提倡这种方式,只是这是一种有效的方式,因此应该作为起点有所帮助。

字体转换器:

$variants = [
    'Black',
    'BlackItalic',
    'Bold',
    'BoldItalic',
    'Hairline',
    'HairlineItalic',
    'Heavy',
    'HeavyItalic',
    'Italic',
    'Light',
    'LightItalic',
    'Medium',
    'MediumItalic',
    'Regular',
    'Semibold',
    'SemiboldItalic',
    'Thin',
    'ThinItalic',
];

foreach ($variants as $variant) {
    \TCPDF_FONTS::addTTFfont(dirname(__FILE__) . '/fonts/Lato-' . $variant . '.ttf', 'TrueTypeUnicode', '', 96);
}

echo 'Done!';

这会将.php.z.ctg.z 文件放在/tecnickcom/tcpdf/fonts 中。

PDF 生成器:

注意$variants 数组中不同的font-family 名称:

$variants = [
    'lato',
    'latob',
    'latobi',
    'latoblack',
    'latoblacki',
    'latohairline',
    'latohairlinei',
    'latoheavy',
    'latoheavyi',
    'latoi',
    'latolight',
    'latolighti',
    'latomedium',
    'latomediumi',
    'latosemib',
    'latosemibi',
    'latothin',
    'latothini'
];

$svg_content = '<svg width="600px" height="800px">';

foreach ($variants as $key => $variant) {
    $svg_content .= '<text x="30" y="' . ( 30 * ( $key + 1 ) ) . '" fill="#ED6E46" font-size="20" font-family="\'' . $variant . '\'" text-anchor="start">The quick brown fox jumped over the lazy dog (' . $variant . ').</text>';
}

$svg_content .= '</svg>';

ob_start();

$pdf = new TCPDF();

$pdf->SetPrintHeader(false);
$pdf->SetPrintFooter(false);
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->SetMargins(0, 0, -1, true);
$pdf->SetAutoPageBreak(false, 0);

$pdf->AddPage();
//$pdf->AddFont('latoblack', '', dirname(__FILE__) . '/fonts/output/latoblack.php');

$pdf->ImageSVG('@' . $svg_content, 0, 0, 300, 300, '', $align='', $palign='C', $border=0, false);

$pdf->Output('example_001.pdf', 'I');

输出:

【讨论】:

  • 完美,谢谢。我现在已经能够生成正确呈现字体的 PDF。阅读您的答案后,我的主要问题是将我的字体放在自定义目录中。一旦我纠正了这个问题,我实际上发现使用像'Lato-Black' 这样的变体名称确实有效——除了'Lato-Semibold',这会导致错误:TCPDF ERROR: Could not include font definition file: latosemi。我不确定它为什么要寻找一个名为latosemi 的文件——我看不到它的引用。任何想法为什么?
  • 不确定,但latosemi 应该是latosemib。听起来像是某个地方的错字。 latosemib 没有为我产生任何错误
猜你喜欢
  • 1970-01-01
  • 2017-02-19
  • 1970-01-01
  • 1970-01-01
  • 2014-12-17
  • 2010-12-08
  • 2016-08-29
  • 2013-01-31
  • 1970-01-01
相关资源
最近更新 更多