Не поддерживает ли рендерер SVG в tcpdf символы UTF-8 выше 00FF? - PullRequest
0 голосов
/ 07 мая 2019

Я пытаюсь напечатать формулу с греческими и латинскими символами из старших SVG-выводов из javascript на внешнем интерфейсе в TCPDF на php-сервере.

Вот соответствующая часть файла SVG:

β(ϴᶜ)m-¹ sr-¹

при выводе в PDF он печатается следующим образом:

?(??)m-1 sr-1

У меня также есть эти символы, отображаемые как просто текст на странице PDF, и это прекрасно работает.

Вот код инициализации:

parent::__construct('P', 'mm','Letter', true, 'UTF-8', false, true); 

Я использую собственный шрифт TTF:

$this->documentFont = \TCPDF_FONTS::addTTFfont($ttfFont, 'TrueTypeUnicode', 
'', 96);

Код, вызываемый для печати ячейки, которая правильно отображает расширенный набор символов UTF-8 выше 00FF:

$this->WriteHTMLCell($x, $y, $this->text);

Это вызов для рендеринга старших SVG, который неправильно отображает символы выше 00FF:

$this->ImageSVG('@'.$image, $x, $y, $width, $height);

В качестве обходного пути я нашел символы, похожие на те, которые мне нужны, в подмножестве 00FF UTF-8:

ß(Øc)m-¹ sr-¹

Это не идеально, но как обходной путь будет работать, пока я не выясню, почему рендеринг SVG не печатает должным образом символы Юникода выше 00FF.

Я попытался добавить символы к осям Highchart в диапазоне Юникода выше 00FF. Вот как я узнал, что это верхний предел того, что будет выводить SVG-рендер.

Я также пытался убедиться, что один и тот же шрифт используется как на переднем, так и на заднем концах в рендере PDF. Пользовательский шрифт TTF, используемый в рендере PDF, - это тот же шрифт, который я указал для использования в интерфейсе, в CSS и в конфигурации HighCharts.

Как я показал в коде ниже, я также пытался окружить рендерер SVG из HighCharts с помощью unescape ();

Визуализация HighCharts:

/**
 * 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:

chart[i].svgData = unescape(chart[i].getSVG());

Я ожидал бы, что рендерер TCPDF SVG напечатает весь диапазон UTF-8. Похоже, что рендерер SVG не способен отображать символы выше 00FF.

1 Ответ

1 голос
/ 10 мая 2019

Первое, что делает анализатор SVG при запуске, - это инициализация стилей SVG. При этом он устанавливает font-family в Helvetica. Поэтому вам необходимо убедиться, что вы явно используете свой собственный шрифт внутри SVG.

Я протестировал линейный график с веб-сайта Highcharts и явно установил атрибут font-family для каждого элемента text и tspan. Следует признать, что это довольно грубое решение, но вы можете использовать его, чтобы быть немного более целенаправленным. Я включил скриншот ниже. (Высокие диаграммы иногда включают другое семейство шрифтов в атрибуты style, но атрибут font-family дает нам простой способ переопределить его, не анализируя и не обновляя строку атрибута style.)

<?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();

(я использовал Dejavusans в приведенном ниже примере, просто заменил заголовок на ваш тестовый текст.)

Demonstration screenshot

...