2015-11-19 58 views
2

我有一個畫布,字形,文本和變量空間爲整數。根據TRadioGroup的ItemIndex(例如,如果ItemIndex = 1,然後在Text等的左側繪製Glyph),我想繪製Glyph和Text到Canvas中。 在任何情況下,Space都必須作爲Glyph和Text之間的空格插入。 即使Canvas的寬度小於Glyph的寬度+ Text的寬度,Glyph和Text也都必須居中在Canvas上。一起繪製字形和WordWrap文本

我試圖執行這個任務,但我有些計算困惑。 附上我的代碼如下:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    R1, R2: TRect; 
    S: String; 
    G, D: Integer; 
    B, C: TBitmap; 
begin 
    S := 'This is an example text to show how WordWrap works'; 
    B := TBitmap.Create; 
    B.LoadFromFile('C:\g.bmp'); 

    C := TBitmap.Create; 
    C.Width := 242; 
    C.Height := 96; 

    Form1.Repaint; 
    Form1.Canvas.Brush.Color := clGreen; 
    Form1.Canvas.FillRect(Rect(0, 0, TrackBar1.Position, C.Height)); 

    // left 
    if RadioGroup1.ItemIndex = 0 then 
    begin 
     R1 := Rect(B.Width + TrackBar2.Position, 0, TrackBar1.Position, C.Height); 
     Form1.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]); 

     Form1.Canvas.Brush.Color := clWebSkyBlue; 
     R2 := Rect(B.Width + TrackBar2.Position, (C.Height - R1.Bottom) div 2, TrackBar1.Position, C.Height); 
     Form1.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]); 

     Form1.Canvas.Draw((TrackBar1.Position - R1.Right - TrackBar2.Position) div 2, (C.Height - B.Height) div 2, B); 
    end; 

    //right 
    if RadioGroup1.ItemIndex = 1 then 
    begin 
     R1 := Rect(B.Width + TrackBar2.Position, 0, TrackBar1.Position, C.Height); 
     Form1.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]); 

     Form1.Canvas.Brush.Color := clWebSkyBlue; 
     R2 := Rect(0, (C.Height - R1.Bottom) div 2, TrackBar1.Position - B.Width - TrackBar2.Position, C.Height); 
     Form1.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]); 

     Form1.Canvas.Draw((TrackBar1.Position + R1.Right - (B.Width*2) + TrackBar2.Position) div 2, (C.Height - B.Height) div 2, B); 
    end; 

    //top 
    if RadioGroup1.ItemIndex = 2 then 
    begin 
     R1 := Rect(0, B.Height + TrackBar2.Position, TrackBar1.Position, C.Height); 
     Form1.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]); 

     G := B.Height + R1.Bottom - R1.Top; 
     D := (C.Height - G) div 2; 

     Form1.Canvas.Brush.Color := clWebSkyBlue; 
     R2 := Rect(0, D + TrackBar2.Position, TrackBar1.Position, C.Height); 
     Form1.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]); 

     Form1.Canvas.Draw((TrackBar1.Position - B.Width) div 2, D - TrackBar2.Position, B); 
    end; 

    //bottom 
    if RadioGroup1.ItemIndex = 3 then 
    begin 
     R1 := Rect(0, B.Height + TrackBar2.Position, TrackBar1.Position, C.Height); 
     Form1.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]); 

     G := B.Height + R1.Bottom - R1.Top; 
     D := (C.Height + G) div 2; 

     Form1.Canvas.Brush.Color := clWebSkyBlue; 
     R2 := Rect(0, D - R1.Bottom - R1.Top + B.Height + TrackBar2.Position, TrackBar1.Position, C.Height); 
     Form1.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]); 

     Form1.Canvas.Draw((TrackBar1.Position - B.Width) div 2, D + TrackBar2.Position, B); 
    end; 

    FreeAndNil(B); 
end; 

如何使用此代碼: 放兩個TrackBars到表和242設置它們的最大價值,爲第一和10個第二; 將TRadioGroup放到窗體上,並按照下一個順序在其Items屬性中設置4個項目:Left,Right,Top,Bottom。因此,當選擇Left或Right項目時,代碼正確工作(正確 - 正如我所預期的那樣),但是當選擇Top或Bottom項目時,Glyph和Text繪畫不正確。我的意思是,例如,我們選擇項目'Top'並單擊Button1。我們看到了什麼?正確的,雕文是在文字上繪製的(詳見圖片)。我試圖打敗,但沒有成功,遺憾的是:

Top glyph's issue

那麼,有沒有辦法改善這種代碼的任何方式?或者我應該用另一種方式來實現我的目標?

P.S. 對不起,我的英文很差;)

編輯 更新源代碼。

+1

歡迎來到SO! C應該是什麼? –

+0

@TomBrunberg謝謝! C是TBitmap。我將在帖子中添加更改。 – Dima

+1

一些額外的提示,你應該在'try ... finally語句中包裝'B'和'C'類變量。你也應該用'B.Free;'而不是'FreeAndNil(B);'最後你需要從內存中釋放'C',就像這樣:'C.Free;' – Craig

回答

1

您對頂部和底部的計算是錯誤的。 您可以直接在位圖畫布上繪製而不是在窗體畫布上繪製。 以下是固定版本:

//top 
    if RadioGroup1.ItemIndex = 2 then 
    begin 
     R1 := Rect(0, B.Height + TrackBar2.Position, TrackBar1.Position, C.Height); 
     C.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]); 
     G := (C.Height div 2); 
     // D is top for centered text rec + glyph size and spacing 
     D := G + ((R1.Height + B.Height + Trackbar2.Position) div 2); 
     C.Canvas.Brush.Color := clWebSkyBlue; 
     R2 := Rect(0, D - R1.Height, TrackBar1.Position, D+R1.Height); 
     C.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]); 
     C.Canvas.Draw((TrackBar1.Position - B.Width) div 2, R2.Top - B.Height - TrackBar2.Position, B); 
    end; 

    //bottom 
    if RadioGroup1.ItemIndex = 3 then 
    begin 
     R1 := Rect(0, 0, TrackBar1.Position, C.Height); 
     C.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]); 
     // G is absolute middle of draw canvas 
     G := (C.Height div 2); 
     // D is top for centered text rec + glyph size and spacing 
     D := G - ((R1.Height + B.Height + Trackbar2.Position) div 2); 
     C.Canvas.Brush.Color := clWebSkyBlue; 
     R2 := Rect(0, D, TrackBar1.Position, D + R1.Height); 
     C.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]); 
     C.Canvas.Draw((TrackBar1.Position - B.Width) div 2, R2.Bottom + TrackBar2.Position, B); 
    end; 
+0

我看到「R1.Height」。 Delphi 2005沒有任何TRect的「高度」,所以我用「R1.Bottom - R1.Top」代替了它。它是否正確?當我試圖執行你的代碼,它完美的作品!非常感謝你! – Dima

+0

我使用XE7,所以Bottom-Top也很好。 – whosrdaddy