4

令我惊讶的是,我发现在 TCanvas 上重复渲染文本在某种程度上是“附加的”。我意识到设置Canvas.Brush.Style:=bsClear是问题的原因,但我确实需要透明且重复地渲染文本(即在OnPaint事件中)。这样做之后,文本看起来不太好。

我怎样才能避免这种情况?

这是一些示例代码;如果您在一个名为btn1.

procedure TForm1.btn1Click(Sender: TObject);
begin
Form1.Canvas.Brush.Style:=bsClear; //if you omit this, everything is OK.
Form1.Canvas.Font.Color:=clRed;
Form1.Canvas.Font.Name:='Times new Roman';
Form1.Canvas.Font.Style:=[fsBold];
Form1.Canvas.Font.Size:=12;
Form1.Canvas.TextOut(50,50,'www.stackoverflow.com');
end;
4

2 回答 2

7

这是因为 GDI 在绘制文本时应用了一些抗锯齿,以使文本看起来更好。这会导致绘制文本之外的一些背景像素在文本附近被涂成红色/微红色。下一次绘制文本时,如果不清除背景,抗锯齿会导致这些带红色的像素变得更红。

您可以将背景清除为Arioch '他的回答中所述,或者如果您确实需要透明且重复地渲染文本,您可以关闭抗锯齿。

TOndrej这个答案中提供了一个很好的函数来指定文本输出质量。使用它,代码变为:

begin
Form1.Canvas.Brush.Style:=bsClear;
Form1.Canvas.Font.Color:=clRed;
Form1.Canvas.Font.Name:='Times new Roman';
Form1.Canvas.Font.Style:=[fsBold];
Form1.Canvas.Font.Size:=12;
SetFontQuality(Form1.Canvas.Font, NONANTIALIASED_QUALITY);  // <--
Form1.Canvas.TextOut(50,50,'www.stackoverflow.com');
end;
于 2012-09-18T08:08:40.793 回答
3

您应该在渲染之前清理背景。

如果控件未公开此类消息/事件,则必须记住最后呈现的文本 TRect(函数 TCanvas.TextExtent 或类似函数)并在呈现下一个文本之前对其进行清理。

有时也可能和更简单(尽管是一种“肮脏和丑陋”的解决方法)将只保留一个透明的 TLabel 漂浮在画布上方的适当位置,并在需要时更改其标题。

于 2012-09-18T07:33:56.790 回答