Delphi Canvas 使用从右到左双向模式的文本输出

Delphi Canvas Textout with RightToLeft BidiMode

我想在 Canvas 上打印从右到左的 Unicode 字符串。我找不到 BidiMode 属性 或类似的东西来完成它。

目前,位于字符串末尾的符号出现在打印在 Canvas 上的文本的第一个字符之前。

FMX

FireMonkey 目前没有任何 BiDi 功能。

VCL

Vcl.TControl class has public DrawTextBiDiModeFlags() and DrawTextBiDiModeFlagsReadingOnly() methods, which help the control decide the appropriate BiDi flags to specify when calling the Win32 API DrawText() 函数。

Vcl.Graphics.TCanvas, its TextOut() and TextRect() methods do not use the Win32 API DrawText() function, they use the Win32 API ExtTextOut() function instead, where the value of the TCanvas.TextFlags property is passed to the fuOptions parameter of ExtTextOut(). The TextFlags property also influences the value of the TCanvas.CanvasOrientation属性中,TextOut()TextRect()内部使用来调整绘图的X坐标。

对于 TCanvas 从右到左的绘图,在 TextFlags 属性.

中包含 ETO_RTLREADING 标志

当 form bidimode 设置为 "bdLeftToRight" 时,使用 "TextOut" 无法成功显示 RTL 文本,所以我通常使用 XXX.Canvas.TextRect(Rect,Text,[tfRtlReading,tfRight]); 对我来说很好.. 我需要检测希伯来语,所以我这样做了:

function CheckHebrew(s: string): boolean;
var
  i: Integer;
begin
  Result := false;
  for i := 1 to Length(s) do
    if (ord(s[i])>=1424) and (ord(s[i])<1535) then
    begin
      Result := true;
      exit;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  tf : TTextFormat;
  r : TRect;
  s : string;
begin
  r.Left := 0;
  r.Top := 0;
  r.Width := Image1.Width;
  r.Height := Image1.Height;
  s := Edit1.Text;
  if CheckHebrew(s) then
    tf := [tfRtlReading,tfRight,tfWordBreak]
  else
    tf := [tfWordBreak];
  Image1.Canvas.FillRect(r);
  Image1.Canvas.TextRect(r,s,tf)
end;