使用RTL BiDi模式时,在Delphi 7中BiDi文本无法正确显示?

时间:2014-04-06 13:39:09

标签: delphi delphi-7 right-to-left bidi

在Delphi 7中,将TMemo放在表单上,​​并在表格OnCreate处理程序中启用RTL BiDiMode,如下所示:

  SysLocale.MiddleEast := True;
  Application.BiDiMode := bdRightToLeft;

如果您使用TMemo将包含BiDi文本的文本文件加载到Lines.LoadFromFile,则文本将无法正确显示。

让我们在文本文件中包含以下文本(这也是显示它的正确方法,例如当用Notepad ++或MS Word显示时):

!ד asd אב!ג
text... text2...

以下是TMemo

中错误显示的方式
אב!ג asd ד!
...text... text2

以下是该文本存储在文本文件中的方式:

21 E3 20 61 73 64 20 E0 E1 21 E2 0D 0A
74 65 78 74 2E 2E 2E 20 74 65 78 74 32 2E 2E 2E

这里只是一个可视化,它是如何存储的(文本永远不会以任何方式呈现,只是为了说明):

!ד asd ג!בא
text... text2...

因此,BiDi文本保存在交替的"块":(RTL块)(LTR块)(RTL块)(LTR块)等。块从左到右的存储顺序是在正确渲染时,您看到它们的方式(从左到右)与块的顺序相同。每个RTL块中字符的存储顺序与正确显示时这些块中字符的查看顺序相反(参见 alef 下注感叹号 gimel 块)。

当RTL BiDiMode未启用时(如果SysLocale.MiddleEast的值为FalseBiDiMode的值为bdLeftToRight,则文本实际上已正确呈现)。

我测试的其他控件(TLabelTCheckboxTRadioButton等)发生了错误的渲染。

当启用RTL TMemo时,查看BiDiMode中显示不正确的文本,我发现块的顺序实际上是颠倒过来的。此外,任何前导中性字符(如!?.等)都会变为尾随字符,反之亦然(例如文本text2后面的三个点)。

考虑到这个问题,我认为问题在于Windows' DrawText函数和呈现BiDi文本时使用的DT_RTLREADING标志。如果我没弄错,这个函数用于渲染大多数控件中的文本。实际上,如果使用带有DrawText标记的DT_RTLREADING在Canvas上渲染BiDi文本,它将以相同的错误方式呈现,如果您不使用DT_RTLREADING ,它将被正确呈现。

我创建了TLabel的后代类,覆盖了它的Paint过程,在呈现文本时永远不会使用DT_RTLREADING,这确实解决了问题。但是,为TCheckboxTRadioButtonTButton等Windows控件修复此问题并不容易。

我也尝试过使用DrawTextEx - 问题仍然存在。 我还尝试使用utf8文本文件和TTntMemo(使用DrawTextW) - 问题仍然存在。

所以,我的问题是:这是一个已知的问题吗?为什么会这样?如果是,是否有修复方法?或者我在这里做错了什么?

0 个答案:

没有答案