Как правильно отображать японские шрифты RTF - PullRequest
5 голосов
/ 01 мая 2009

Я работаю над приложением в Delphi 2009, которое интенсивно использует RTF, отредактированное с использованием TRichEdit и TLMDRichEdit. Пользователи, которые вводили текст на японском языке в эти элементы управления RTF, периодически отправляли отчеты о том, что текст на японском языке отображается как бессмысленный при перезагрузке контента как в Win XP, так и в Vista с установленной поддержкой восточного языка.

Как правило, английский и японский языки смешаны и в основном отображаются без проблем, например:

Inventory turns partnerships.  在庫回転率の

(мои извинения, если текст на японском языке неверен - я не говорю и не читаю на языке).

Довольно часто, однако, только японская часть текста будет бессмысленной, например:

ŒÉñ?“]-¦Œüã‚Ì·•Ê‰?-vˆö‚ðŽû‰v‚ÉŒø‰?“I‚ÉŒ‹‚т‚¯‚é’mŽ¯‚ª‘÷Ý‚·‚é?(マーケットセクター、
見込み客の優  先順位と彼らに販売する知識)

По результатам обширного онлайн-поиска выясняется, что проблема связана со шрифтами, сохраненными как часть RTF. Шрифты, представленные в японской языковой версии Windows, не обязательно совпадают с английской версией в США. Можно программно заменить шрифты в файле RTF, что дает практически приемлемый результат, т.е.

-D‚‚スƒIƒyƒŒ[ƒVƒ・“‚ニƒƒWƒXƒeƒBƒbƒN‚フƒpƒtƒH[ƒ}ƒ“ƒX‚-˜‰v‚ノŒ‹‚ム‚ツ‚ッ‚ネ‚「‚±ニ‚ヘ?A‘‚「‚ノ-ウ‘ハ‚ナ‚ ‚驕B‚サ‚‚ヘAl“セ‚オ‚ス・‘P‚フˆロ‚ƒƒXƒN‚ノ‚ウ‚‚キB

Тем не менее, в нем все еще довольно много «мусорных» символов, которые неправильно распознаются как японские символы. Глядя на сырой RTF, вы увидите следующее:

-D\'82\'82\u65405?\'83I\'83y\'83\'8c[\'83V\'83\u12539?\ldblquote\'82\u65414?

Ясно, что символы Юникода отображаются правильно, но, например, пара символов \ '82 \ '82 должна быть чем-то другим? Я предполагаю, что это фактически представляет собой двухбайтовый символ некоторого вида, который по какой-то таинственной причине был закодирован как два отдельных символа, а не как один символ Unicode.

Существует ли общий (относительно) надежный способ получить RTF, содержащий восточные языки, и надежно отобразить его снова?

Для полноты картины я обновил таблицу шрифтов RTF следующим образом:

  • Заменено название шрифта "? L? R? O? S? V? B? N;" с "\ '82 \ '6c \ '82 \ '72 \ '82 \' 6f \ '83 \ '53 \ '83 \ '56 \ '83 \ '62 \ '83 \ '4e;"
  • Обновлены имена шрифтов, заменив "\ froman \ fprq1 \ fcharset0" на "\ fnil \ fprq1 \ fcharset128"
  • Обновлены имена шрифтов, заменив "\ froman \ fprq1 \ fcharset238" на "\ fnil \ fprq1 \ fcharset128"
  • Обновлены имена шрифтов, заменив "\ froman \ fprq1" на "\ fnil \ fprq1 \ fcharset128"
  • Замена названия шрифта "?? ?????;" с "\ '82 \ '6c \ '82 \ '72 \ '82 \' 6f \ '83 \ '53 \ '83 \ '56 \ '83 \ '62 \ '83 \ '4e;"

Обновление: обновление имен шрифтов само по себе не имеет значения. Язык, кажется, большая проблема. Я видел несколько сайтов, обсуждающих способы преобразования отображения японского RTF в то, с чем справится большинство читателей, но я пока не нашел решения, см., Например: здесь и здесь .

Ответы [ 2 ]

1 голос
/ 06 мая 2009

Я видел нечто подобное, но не с японскими шрифтами. Просто специальные символы, такие как микро (как в микролитрах) и верхние индексы. Проблема заключалась в том, что хотя строка RTF, которую я отправлял пользователю с веб-страницы ASP.NET, была правильной (я мог видеть закодированный поток RTF с помощью Fiddler2), когда MS Word фактически открывал RTF, он добавил кучу мусора коды, подобные тому, что я вижу в вашем образце.

Что я сделал, так это запустил весь текст RTF через процедуру преобразования, которая поменяла местами все символы по ascii 127 до их особого эквивалента в Unicode. Так я бы получил что-то вроде \ uc1 \ u181? (микро) для специальных символов. Когда я это сделал, Word смог открыть файл без проблем. По иронии судьбы, он перекодировал \ uc1 \ uxxx? обратно к их RTF экранированным эквивалентам.

Private Function ConvertRtfToUnicode(ByVal value As String) As String

    Dim ch As Char() = value.ToCharArray()
    Dim c As Char
    Dim sb As New System.Text.StringBuilder()
    Dim code As Integer

    For i As Integer = 0 To ch.Length - 1
        c = ch(i)
        code = Microsoft.VisualBasic.AscW(c)
        If code <= 127 Then
            'Don't need to replace if one of your typical ASCII codes
            sb.Append(c)
        Else
            'MR: Basic idea came from here http://www.eggheadcafe.com/conversation.aspx?messageid=33935981&threadid=33935972
            '  swaps the character for it's Unicode decimal code point equivalent
            sb.Append(String.Format("\uc1\u{0:d}?", code))
        End If
    Next

    Return sb.ToString()

End Function

Не уверен, поможет ли это вашей проблеме, но она работает для меня.

1 голос
/ 01 мая 2009

Я предполагаю, что изменение имен шрифтов в RTF, вероятно, ухудшило ситуацию. Если шрифт, указанный в RTF, не является шрифтом Unicode, то символы, которые должны быть отображены в этом шрифте, обязательно будут закодированы как Shift-JIS, а не как Unicode. И затем то же самое будут и другие символы в тексте. Таким образом, обработка всего этого как Unicode или добавление текста Unicode вызовет искажение, которое вы видите. Вам необходимо установить, является ли импортируемый вами RTF кодированный Shift-JIS или Unicode, а также является ли машина, на которой вы работаете (и, следовательно, формат ввода D2009 по умолчанию), японской или нет. В Японии, если текстовый файл не имеет спецификации Unicode, обычно это Shift-JIS (но не всегда).

...