delphi - 为什么当我在一个语句中不按顺序打印它们时,Canvas 中的 TextOut 将方框绘图字符连接起来有间隙?

标签 delphi canvas textout

我在项目中使用字体“Consolas”和/或“Courier New”来绘制类似 MS-DOS 的环境。在这个项目中,如果我使用 TextOut(TCanvas 的)在一条语句中按顺序打印 Box Drawing 字符,一切都很好,例如它打印“──────────”但是如果我处理每个字符以打印它们分别地,每个字符之间会有一个空隙,就像这样:“------------”。 这是一个供您手动测试的示例:

  ...

  Canvas.Font.Size := 12;

  w := Canvas.TextWidth('╬');
  h := Canvas.TextHeight('╬');

  Canvas.TextOut(100, 100, '╬╬');

  Canvas.TextOut(100, 100 + h, '╬');
  Canvas.TextOut(100 + w, 100 + h, '╬');

  Canvas.TextOut(100, 100 + h * 2, '╬');
  Canvas.TextOut(100 + w, 100 + h * 2, '╬');

输出是:

Screenshot of output: white characters on a blue background. While the first line has connected characters, the remaining lines each display a very small gap between the characters.

如您所见,它们在垂直方向上连接良好,但在水平方向上存在间隙。

我该如何解决?请注意,我在一个数组中绘制了我想要的内容,然后一个过程按如下方式打印该数组:

  th := Canvas.TextHeight('A');
  tw := Canvas.TextWidth('A');
  for i := 0 to MaxWidth - 1 do
    for j := 0 to MaxHeight - 1 do
    begin
      Canvas.Brush.Color := fChars[i, j].BGColor;
      Canvas.Font.Color := fChars[i, j].FGColor;
      Canvas.TextOut(i * tw, j * th, fChars[i, j].Character);
    end;

最佳答案

如果您使用 DrawText() 而不是 Canvas.TextOut() 它会起作用。 SO answer中解释了原因.它与不同 Windows API 在某些字体上应用的字符间距有关。

这是一个完整的工作示例:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    procedure FormPaint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
        FFont: TFont;
  public
    { Public declarations }
  end;

type TMyChar = record
  BGColor : TColor;
  FGColor : TColor;
  Character : Char;
end;

const
  FWidth : Integer = 9;
  FHeight : Integer = 9;

var
  Form1: TForm1;
  Fchars : Array[0..9,0..9] of TMyChar;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

var
 i,j : Integer;

begin
  Canvas.Font.Size := 12;
  Canvas.Font.Name := 'Courier New';
  for i := 0 to FWidth do
    for j := 0 to FHeight do
    begin
     FChars[i,j].Character:= '╬';
     FChars[i,j].BGColor := clBlue;
     FChars[i,j].FGColor := clYellow;
    end;

end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 FFont.Free;
end;

procedure TForm1.FormPaint(Sender: TObject);
var w,h,i,j: Integer;
    FRect : TRect;
begin
  h := Canvas.TextHeight('A');
  w := Canvas.TextWidth('A');
  for i := 0 to FWidth do
    for j := 0 to FHeight do
    begin
      Canvas.Brush.Color := fChars[i, j].BGColor;
      Canvas.Font.Color := fChars[i, j].FGColor;
//      Canvas.TextOut(i * w, j * h, fChars[i, j].Character);
      FRect := Rect(i * w, j * h, i * w + w, j * h + h);
      DrawText(Canvas.Handle, (fChars[i, j].Character), 2, FRect, DT_LEFT);
    end;
  end;

end.

关于delphi - 为什么当我在一个语句中不按顺序打印它们时,Canvas 中的 TextOut 将方框绘图字符连接起来有间隙?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62882655/

相关文章:

javascript - Canvas 游戏中圆圈边界的错误渲染

winapi - 是否可以确定Windows为字体链接选择的字体?

WinApi DrawText 和 TextOut 无法显示 unicode 字符 U+5167

delphi - 尝试在标准用户上写入 HKLM 时如何不触发异常?

德尔福XE2总成

delphi - 在Delphi中将多维数组作为参数传递

javascript - Canvas Audio Visualizer 未出现在 Safari 中

javascript - Canvas 线条表现异常

c++ - 如何使用 Win32 TextOut 绘制波浪下划线

delphi - H2077 里面的 try finally 被 goto 阻塞 - 这是东京的编译器缺陷吗?