Подтвердить что ты не робот

Prawn:: Errors:: IncompatibleStringEncoding: ваш документ содержит текст, который несовместим с набором символов Windows-1252

Ниже мой PDF файл Prawn для создания имени в PDF файле

def initialize(opportunity_application)
  pdf = Prawn::Document.new(:page_size => [1536, 2048], :page_layout => :landscape)
  cell_1 = pdf.make_cell(content: "Eylül Çamcı".force_encoding('iso-8859-1').encode('utf-8'), borders: [], size: 66, :text_color => "000000", padding: [0,0,0,700], font: "app/assets/fonts/opensans.ttf")

  t = pdf.make_table [[cell_1]]
  t.draw
  pdf.render_file "tmp/mos_certificates/application_test.pdf"
end

При отображении имени Eylül Çamcı, которое является турецким, я получаю следующую ошибку -

Prawn::Errors::IncompatibleStringEncoding: Your document includes text that not compatible with the Windows-1252 character set.
If you need full UTF-8 support, use TTF fonts instead of PDF built-in fonts.

Я уже использую шрифт TTF, который поддерживает символы в этом имени, что я могу сделать, чтобы правильно напечатать имя?

4b9b3361

Ответ 1

Это швы Турецкий отсутствует в iso-8859-1.

С другой стороны, iso-8859-9 должен работать.

Итак, вы можете попытаться изменить свой код, как (проверьте номер iso, который я изменил):

...
cell_1 = pdf.make_cell(content: "Eylül Çamcı".force_encoding('iso-8859-9').encode('utf-8'), borders: [], size: 66, :text_color => "000000", padding: [0,0,0,700], font: "app/assets/fonts/opensans.ttf")
...

И fun link, которая связана не только с набором символов, но и с другими различиями в интернализации для Турции.


Изменить 1: я сделал базовую проверку, кажется, что текст уже находится в UTF-8. Итак, зачем нужно переходить на iso-8859 и вернуться в UTF-8?

Не можете ли вы попробовать "Eylül Çamcı".force_encoding('utf-8')?

irb(main):013:0> "Eylül Çamcı".encoding
=> #<Encoding:UTF-8>
irb(main):014:0> "Eylül Çamcı".force_encoding('UTF-8')
=> "Eylül Çamcı"
irb(main):015:0>

Изменить 2: Также вы можете проверить свой путь шрифта? Оба шрифта существуют, и путь правильный?

#Rails.root.join('app/assets/fonts/opensans.ttf')
cell_1 = pdf.make_cell(content: "Eylül Çamcı".force_encoding('utf-8'), borders: [], size: 66, :text_color => "000000", padding: [0,0,0,700], font: Rails.root.join('app/assets/fonts/opensans.ttf'))

Ответ 2

Из этого anwser о Принудительные строки к UTF-8 из любой кодировки:

"Форсировать" кодировку легко, однако она не преобразует символы просто измените кодировку:

str = str.force_encoding("UTF-8")
str.encoding.name # => 'UTF-8'

Если вы хотите выполнить преобразование, использовать кодировку

В самом деле, как сказал @MehmetKaplan:

Это швы Турецкий отсутствует в iso-8859-1.

С другой стороны, iso-8859-9 должен работать.

Поэтому вам больше не понадобится force_encoding, но просто encode

[37] pry(main)> "Eylül Çamcı".encode('iso-8859-1')
Encoding::UndefinedConversionError: U+0131 from UTF-8 to ISO-8859-1
from (pry):39:in `encode'
[38] pry(main)> "Eylül Çamcı".encode('iso-8859-9')
=> "Eyl\xFCl \xC7amc\xFD"

Это означает, что вы должны полностью удалить UTF-8 в свой код.

content: "Eylül Çamcı".encode('iso-8859-9'),

Ответ 3

Я не уверен, что помню, как работает Креветка, но файлы PDF не поддерживают UTF-8, которая по умолчанию является строкой Ruby для объектов String.

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

Обходным путем является либо использование карт символов (CMaps) - либо пользовательских CMaps, либо заранее определенных (шрифт BYO).

Как правило, файлы PDF включают встроенный шрифт (или подмножество шрифта) и CMap, отображающий значение байта (или нескольких байтов) в желаемый глиф шрифта. то есть отображение 97, которое является "а" в ASCII, к значению глифа при использовании указанного шрифта.

В прошлый раз, когда я использовал Prawn, я думаю, что он поддерживал шрифты TTF и автоматически создавал карты шрифтов, используя строки UTF-8 для ввода текста, но вам нужно загрузить соответствующий шрифт в креветку и не забудьте использовать его!.

Вы можете увидеть пример в этом ответе.

Удачи!

ИЗМЕНИТЬ

Я обновил ответ, чтобы отразить комментарии @mkl.

@mkl указал, что другие кодировки поддерживаются или возможны (шрифт BYO), включая предопределенную некоторую многобайтовую кодировку (в которой используются предопределенные CMaps).