令我惊讶的是,我发现在TCanvas上重复渲染文本在某种程度上是“附加的”。我意识到设置Canvas.Brush.Style:=bsClear
是问题的原因,但我确实需要透明地重复地呈现文本(即在OnPaint
事件中)。执行此操作后,文本看起来不太好。
我该如何避免?
这是一些示例代码;如果您对名为btn1
的TButton进行多次点击,则可以看到效果。
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;
答案 0 :(得分:7)
这是因为GDI在绘制文本时应用了一些抗锯齿,使文本看起来更好。这会导致绘制文本外部的一些背景像素在文本附近被涂成红色/红色。当您下次绘制文本时,如果您不清除背景,抗锯齿会导致这些偏红的像素变得更红。
您可以将背景清除为Arioch 'The中所述的answer,或者如果您确实需要透明且重复地渲染文本,则可以关闭抗锯齿功能。
TOndrej在this answer中提供了一个很好的功能,用于指定文本输出质量。使用它,代码变为:
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;
答案 1 :(得分:3)
你应该在渲染之前清理背景。
如果控件没有公开这样的消息/事件,那么你必须记住最后渲染的文本TRect(函数TCanvas.TextExtent或类似的东西)并在渲染下一个文本之前清除它。
有时可能更简单(虽然是一种“肮脏和丑陋”的解决方法)只是保持透明的TLabel在画布上方漂浮在适当的位置并在需要时更改其标题。