在我的Delphi應用程序中,我需要使用GDI和GDI +繪製多行文本。 我有這些項目:使用GDI和GDI繪製旋轉多行文本+
- 要畫的文本;
- 旋轉角度(文字可能會旋轉);
- 最大寬度(想象包含文本的矩形,我對矩形寬度有限制,但對於矩形高度沒有限制);
- 字體名稱和文字高度;
有沒有一種簡單的方法可以用GDI和GDI +繪製這個文本? 我找不到關於它的GDI和GDI +函數。
在我的Delphi應用程序中,我需要使用GDI和GDI +繪製多行文本。 我有這些項目:使用GDI和GDI繪製旋轉多行文本+
有沒有一種簡單的方法可以用GDI和GDI +繪製這個文本? 我找不到關於它的GDI和GDI +函數。
tl; dr
使用graphics32和GR32_Text。
對於GDI,最簡單的方法是使用字體的擒縱機構和定向性。例如:
procedure TForm1.PaintBox1Paint(Sender: TObject);
const
Text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do '
+ 'eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim '
+ 'ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut '
+ 'aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit '
+ 'in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur '
+ 'sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt '
+ 'mollit anim id est laborum.';
var
angle: Integer;
Canvas: TCanvas;
lf: LOGFONT;
R: TRect;
begin
Canvas := PaintBox1.Canvas;
Canvas.Brush.Style := bsClear; // Set the brush style to transparent.
lf := Default(LOGFONT);
lf.lfHeight := 20;
lf.lfCharSet := DEFAULT_CHARSET;
lf.lfFaceName := 'Times New Roman';
angle := 15;
lf.lfEscapement := 10*angle;//lfEscapement measured in 1/10th of degree
lf.lfOrientation := lf.lfEscapement;
Canvas.Font.Handle := CreateFontIndirect(lf);
R := PaintBox1.ClientRect;
inc(R.Top, 200);
DrawText(Canvas.Handle, Text, -1, R, DT_NOCLIP or DT_WORDBREAK);
end;
產生相當奇怪的佈局:
使用SetWorldTransform
給出了不同的佈局,但質量仍然較差:
procedure TForm1.PaintBox1Paint(Sender: TObject);
const
Text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do '
+ 'eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim '
+ 'ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut '
+ 'aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit '
+ 'in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur '
+ 'sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt '
+ 'mollit anim id est laborum.';
var
angle: Integer;
Transform: TXForm;
Canvas: TCanvas;
lf: LOGFONT;
R: TRect;
begin
Canvas := PaintBox1.Canvas;
angle := 15;
Transform := Default(TXForm);
SinCos(DegToRad(-angle), Transform.eM12, Transform.eM11);
Transform.eM22 := Transform.eM11;
Transform.eM21 := -Transform.eM12;
SetGraphicsMode(Canvas.Handle, GM_ADVANCED);
SetWorldTransform(Canvas.Handle, Transform);
Canvas.Brush.Style := bsClear; // Set the brush style to transparent.
lf := Default(LOGFONT);
lf.lfHeight := 20;
lf.lfCharSet := DEFAULT_CHARSET;
lf.lfFaceName := 'Times New Roman';
Canvas.Font.Handle := CreateFontIndirect(lf);
R := PaintBox1.ClientRect;
inc(R.Top, 200);
inc(R.Left, Round(200*Transform.eM12));
DrawText(Canvas.Handle, Text, -1, R, DT_NOCLIP or DT_WORDBREAK);
end;
坦率地說,我認爲你不會使用這兩種方法獲得好的結果。如果我是你,我會用一個好的圖書館,如與安格斯約翰遜的GR32_Text graphics32:
對於GDI +,結果是大致相同的GDI。示例代碼將是:
uses
GDIPAPI, GDIPOBJ;
....
{$TYPEDADDRESS ON}
procedure TForm1.PaintBox1Paint(Sender: TObject);
const
Text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do '
+ 'eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim '
+ 'ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut '
+ 'aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit '
+ 'in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur '
+ 'sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt '
+ 'mollit anim id est laborum.';
var
Graphics: TGPGraphics;
Font: TGPFont;
Brush: TGPBrush;
lf: LOGFONT;
begin
Graphics := TGPGraphics.Create(PaintBox1.Canvas.Handle);
try
Graphics.SetTextRenderingHint(TextRenderingHintSystemDefault);
lf := Default(LOGFONT);
lf.lfHeight := 20;
lf.lfCharSet := DEFAULT_CHARSET;
lf.lfFaceName := 'Times New Roman';
Font := TGPFont.Create(PaintBox1.Canvas.Handle, @lf);
try
Brush := TGPSolidBrush.Create(MakeColor(0, 0, 0));
try
Graphics.RotateTransform(-15);
Graphics.DrawString(
Text,
-1,
Font,
MakeRect(0.0, 150.0, 450.0, 600.0),
nil,
Brush
);
finally
Brush.Free;
end;
finally
Font.Free;
end;
finally
Graphics.Free;
end;
end;
和輸出:
還是蠻蹩腳看在我看來。所以爲了獲得最好的質量,我會推薦使用GR32_Text的graphics32。
...或反穀物幾何庫... – TLama
基礎知識似乎很簡單:
procedure TForm2.FormPaint(Sender: TObject);
const
S = 'Multiline sample text with 50 degrees rotation';
H = 20;
A = -50;
var
R: TRect;
NewFont: HFONT;
OldFont: HFONT;
TextHeight: Integer;
begin
R := ClientRect;
InflateRect(R, -20, -20);
NewFont := CreateFont(-H, 0, A * 10, A * 10, FW_NORMAL, 0, 0, 0,
DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH, 'Tahoma');
try
OldFont := SelectObject(Canvas.Handle, NewFont);
DrawText(Canvas.Handle, S, -1, R, DT_LEFT or DT_BOTTOM or
DT_WORDBREAK or DT_NOCLIP);
finally
DeleteObject(SelectObject(Canvas.Handle, OldFont));
end;
end;
但它不是爲多行文本:
你需要做的是不要使用在字體的水平旋轉什麼,但在畫布級,與SetWorldTransform。
...將工作稍後再舉一個例子。 – NGLN
我相信[這篇文章](http://stackoverflow.com/a/10633410/800214)會讓你開始... – whosrdaddy