2012-09-18 15 views
4

令我驚訝的是,我發現在TCanvas上重複渲染文本是某種「附加」的。我意識到設置Canvas.Brush.Style:=bsClear是問題的原因,但我確實需要透明地重複呈現文本(即在OnPaint事件中)。這樣做後,文字看起來不太好。TCanvas上的「添加劑」文字渲染?

我怎樣才能避免這種情況?

下面是一些示例代碼;如果您對稱爲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

我想你在這裏做的是從Windows概念POV非常錯誤。畫布是不穩定的東西,需要重新繪製。它不是持久的。將窗體移動到屏幕外部或將其懸停在另一個窗口中應該會刪除該圖片。遵循Windows方式使用TPaintBox並根據需要繪製所需內容,強制反Windows持久方式使用TImage來保留繪圖。 –

+0

@Arioch>當然......但是這是非常簡單的例子...只是在點擊按鈕的處理程序示範 – lyborko

+3

停止繪畫和響應'WM_PAINT'開始繪畫。在VCL中,你通常會使用'TPaintBox'來屏蔽Win32 API。我再說一遍,只有響應'WM_PAINT'才能繪製。 –

回答

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; 
3

您應該在呈現前清理背景。

如果這樣的消息/事件沒有被控制曝光,那麼你必須記得最後呈現的文本TRect(功能TCanvas.TextExtent或者類似的),並呈現下一個文本之前清潔。

也有時可能和更簡單(雖然是種「骯髒和醜陋」的解決方法)將保持一個透明的TLabel漂浮在畫布上方的適當位置,並在需要時更改其標題。