Reputation: 146
I'm trying to print a formula with greek and latin characters from the highcharts SVG output from javascript on the front end into TCPDF on the php backend.
Here's the relevant portion of the SVG file:
β(ϴᶜ)m-¹ sr-¹
when rendered on to the pdf it prints as follows:
?(??)m-1 sr-1
I also have these characters rendering as just text on the pdf page, and that works fine.
Here's the initialization code:
parent::__construct('P', 'mm','Letter', true, 'UTF-8', false, true);
I'm using a custom TTF font:
$this->documentFont = \TCPDF_FONTS::addTTFfont($ttfFont, 'TrueTypeUnicode',
'', 96);
Code called to print cell, that correctly renders extended UTF-8 characterset above 00FF:
$this->WriteHTMLCell($x, $y, $this->text);
This is the call to render the highcharts SVG, that is not correctly rendering characters above 00FF:
$this->ImageSVG('@'.$image, $x, $y, $width, $height);
For a work around, I found characters similar to what I need in the 00FF subset of UTF-8:
ß(Øc)m-¹ sr-¹
It's not perfect, but as a work around it will work until I can figure out why the SVG rendering is not properly printing unicode characters above 00FF.
I have tried adding characters to the Highchart axes in the unicode range above 00FF. That is how I found out that appears to be the upper limit of what the SVG renderer will print.
I have also tried making sure the same font is being used on both the front end and the back end, in the PDF renderer. The custom TTF font being used in the PDF renderer, is the same font I'm specifying for use on the front end, in CSS and in the HighCharts configuration.
As I've shown in the code below, I've also tried surrounding the SVG renderer from HighCharts with unescape();
HighCharts rendering:
/**
* inserts a highchart line chart into the HTML document at specified point
* @param {HTMLElement} chartContainer where this chart is rendered to
* @param {object} chartConfig config object with chart options.
* @param {array} seriesData two dimensional array to plot
* @param {string} seriesName name of series being plotted
* @return {Highcharts} highcharts object to be inserted - allows later referencing
*/
function addChart(chartContainer, chartConfig, seriesData, seriesName)
{
return new Highcharts.Chart({
chart: {
animation: false,
type: 'line',
renderTo: chartContainer,
zoomType: 'y'
},
title: {
text: chartConfig.title
},
xAxis: {
title: {
text: 'DUT DATA - ' + chartConfig.uom
},
gridLineDashStyle: 'solid',
gridLineWidth: 2,
minorTicks: true,
minorGridLineDashStyle: 'longdash',
startOnTick: true,
endOnTick: true,
max: chartConfig.xMax,
min: chartConfig.xMin
},
yAxis: {
title: {
text: 'Residuals'
},
gridLineDashStyle: 'solid',
gridLineWidth: 2,
minorTicks: true,
minorGridLineDashStyle: 'longdash',
tickWidth: 2,
lineWidth: 1,
max: chartConfig.yMax,
min: chartConfig.yMin
},
plotOptions: {
line: {
animation: false
}
},
series: [{
name: seriesName,
point: {
events: {
click: function () {
console.log('Category: ' + this.category + ', value: ' + this.y);
}
}
},
animation: false,
showInLegend: true,
data: seriesData
}],
exporting: {
enabled: true
},
credits: {
enabled: false
}
});
}
SVG creation:
chart[i].svgData = unescape(chart[i].getSVG());
I would expect the TCPDF SVG renderer to print the entire UTF-8 range. It appears the SVG renderer does not have the capability to render characters above 00FF.
Upvotes: 0
Views: 609
Reputation: 4029
One of the first things the SVG parser does when it starts up is initialize the SVG styles. In doing so, it sets the font-family
to Helvetica. So you'll need to ensure that you're explicitly using your custom font inside your SVG.
I tested with a line graph from Highcharts' website and explicitly setting the font-family
attribute on every text
and tspan
element seemed to do the trick. Admittedly, it is a rather blunt solution, but you can tool it to be a little more targetted. I included a screenshot below. (Highcharts will sometimes include a different font family in style
attributes, but the font-family
attribute gives us an easy way to override it without parsing and updating the style
attribute string.)
<?php
$svgdom = new DOMDocument();
//My extract from Highcharts did not include the XML declaration, so I add it.
//TCPDF might assume it's UTF-8, so this may not be needed.
//[Edit: Checked, TCPDF does, but we're working on it before that stage I figure
//it's best to include the xml declaration if it's not already there.]
$svgdom->loadXML('<?xml version="1.0" encoding="utf-8" ?>'.$image);
$xpath = new DOMXPath($svgdom);
$textitems = $xpath->query('//*[local-name() = "text" or local-name() = "tspan"]');
foreach($textitems as $element) {
$element->setAttribute('font-family', $font);
}
$image = $svgdom->saveXML();
(I used Dejavusans for the example below, simply replaced the heading with your test text.)
Upvotes: 1