5

我正在开发 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?

显然,Unicode 字符被正确呈现,但例如 \'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 的显示转换为大多数读者可以处理的内容,但我还没有找到解决方案,例如: herehere

4

2 回答 2

1

我的猜测是,更改 RTF 中的字体名称可能会使事情变得更糟。如果 RTF 中指定的字体不是 Unicode 字体,那么在该字体中渲染的字符肯定会被编码为 Shift-JIS,而不是 Unicode。文本中的其他字符也是如此。因此,将整个事物视为 Unicode,或附加 Unicode 文本,将导致您看到的损坏。您需要确定您导入的 RTF 是编码为 Shift-JIS 还是 Unicode,以及您正在运行的机器(以及因此 D2009 默认输入格式)是否为日语。在日本,如果文本文件没有 Unicode BOM,它通常是 Shift-JIS(但并非总是如此)。

于 2009-05-01T09:12:20.067 回答
1

我看到了类似的东西,但不是日文字体。只是特殊字符,如微(如微升)和上标。问题是即使我从 ASP.NET 网页发送给用户的 RTF 字符串是正确的(我可以看到使用 Fiddler2 编码的 RTF 流),当 MS Word 实际打开 RTF 时,它添加了一堆垃圾转义类似于我在您的示例中看到的代码。

我所做的是通过一个转换例程运行整个 RTF 文本,该例程将 ascii 127 上的所有字符交换为其特殊的 unicode 点等价物。所以我会得到类似 \uc1\u181 的东西?(micro) 用于特殊字符。当我这样做时,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

不确定这是否会帮助您解决问题,但它对我有用。

于 2009-05-05T23:05:46.520 回答