TCPDF UTF-8. Литовские символы не отображаются

Существует два способа, которыми может быть определена утечка памяти.

Первый, если данные не освобождены, когда больше нет, имеет любые ссылки на него, те данные недостижимы (если Вы не имеете некоторый поврежденный указатель или читаете мимо данных в буфере или чем-то). В основном, если Вы не освобождаете/удаляете данные, выделенные на "куче", это становится неприменимым и просто тратит впустую память.

могут быть случаи, где указатель потерян, но данные все еще доступны. Например, если Вы храните указатель в интервале или храните смещение к указателю (использующий адресную арифметику с указателями), можно все еще вернуть исходный указатель.

В этом первом определении, данные обрабатываются сборщиками "мусора", которые отслеживают количество ссылок на данные.

114-секундный, память по существу пропущена, если она не освобождена/удалена когда в последний раз используемый. На это можно сослаться, и сразу свободно-способное, но ошибка была сделана, чтобы не сделать так. Может быть допустимая причина (например, в случае, где деструктор имеет некоторый странный побочный эффект), но это указывает на плохое проектирование программы (по-моему).

Этот второй тип памяти, просачивающейся часто, происходит при записи небольших программ, которые используют файл IO. Вы открываете файл, пишете Ваши данные, но не закрываете его, как только Вы сделаны. ФАЙЛ* может все еще быть в объеме, и легко closeable. Снова, может быть некоторая причина того, чтобы сделать это (такие как блокировка доступа для записи другими программами), но мне это - флаг плохого дизайна.

В этом втором определении, данные не обрабатываются сборщиками "мусора", если компилятор/интерпретатор не будет умным (или немым) достаточно, чтобы знать, что это не будет использоваться больше, и это освобождение данных не вызовет побочных эффектов.

25
задан display_name 7 January 2014 в 13:09
поделиться

5 ответов

С пакетом TCPDF по умолчанию протестировано dejavusans и freeserif , и оба шрифта работают с литовскими символами. Я также набрал несколько русских символов, и они тоже работали. Я использовал этот код для проверки:

$this->pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); 
$this->pdf->AddPage();
$this->pdf->SetFont('dejavusans', 'B', 20); // UTF8 fonts with lithuanian support: freeserif, dejavusans
$this->pdf->Write(0, 'ąžūčšęėųįĄŽŪČŠĘĖŲĮ Превед Кросавчег!', '', 0, 'C', true, 0, false, false, 0);
1
ответ дан 28 November 2019 в 17:45
поделиться

IIRC, вы можете определить кодировку при создании нового шрифта, , как описано здесь . В противном случае вы должны использовать кодировку, которая была определена при создании шрифта. Похоже, что все шрифты, которые поставляются с TCPDF, используют WinAnsiEncoding ... кодовая страница 1252. a.k.a.

Неуклюжий, но эффективный.

3
ответ дан 28 November 2019 в 17:45
поделиться

TCPDF довольно сложен с utf8. Лучший способ добиться того, чего вы хотите - это встроить шрифт в сам сгенерированный файл PDF. Вы можете использовать шрифт freeserif из пакета TCPDF, он содержит все символы utf8, показывает абсолютно любой символ любого языка, но добавляет ~ 700 КБ к выходному файлу. Это, вероятно, самый простой способ получить нужные символы, если размер файла не имеет значения.

Вы также можете сделать свой собственный шрифт для вставки, содержащий нужные вам символы. Это, вероятно, лучшее решение, оно универсально и мало по размеру, но более сложное.

В качестве альтернативы, вы можете ретранслировать основные шрифты, которые взяты из системы и, если не найдены, заменены заменой. Это делает выходной файл чрезвычайно легким, но добавляет необходимость поднабора шрифтов для получения экзотических символов. Лично я не имел успеха с этим, поэтому я все еще думаю, что внедрение шрифта - лучшее решение, которое также оказывается более универсальным.

30
ответ дан 28 November 2019 в 17:45
поделиться

Просто обнаружил эту же ситуацию при попытке визуализации румынского текста с использованием шрифта Helvetica по умолчанию Проведя некоторое исследование, я обнаружил, что библиотека tcpdf рассматривает свои шрифты по умолчанию (называемые «базовыми» шрифтами) как символы Latin1, поэтому даже если вы скажете ей использовать кодировку UTF-8 и установите флаг unicode, она буквально переведет ваш текст до Latin1 эквивалентов до рендеринга. Поведение библиотеки по умолчанию, если она находит эквивалент Latin1, переводит каждый символ, для которого она может найти эквивалент, иначе она переводит символ как «?».

Это можно найти внутри класса TCPDF в следующей цепочке методов: Write() -> Cell() -> getCellCode() -> _escapetext().

Внутри _escapetext() вы можете видеть, что он проверяет $this->isunicode, затем проверяет выбранный шрифт, чтобы увидеть, является ли его тип core | TrueType | Type1 . Если это так, он примет для вас строку «латинизирует» ее с помощью метода UTF8ToLatin1(). Это где '?' переводы выполняются.

Я бы порекомендовал использовать пользовательский шрифт Unicode (например, Deja Vu Sans), который похож на шрифт по умолчанию, который вам нужен. Это сработало для меня в моей текущей ситуации.

9
ответ дан 28 November 2019 в 17:45
поделиться

Установите шрифт на freeserif, он будет работать. Я проверил.

$pdf->SetFont('freeserif', '', 14, '', true);
9
ответ дан 28 November 2019 в 17:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: