Vấn đề của tôi:
Tôi hiện đang làm việc trên điều khiển người dùng tùy chỉnh hiển thị các đoạn văn bản (mỗi phông chữ có phông chữ khác nhau) trên một dòng. Tôi muốn căn chỉnh tất cả các bit của văn bản chính xác dọc theo đường cơ sở chung. Ví dụ:Sử dụng GDI +, cách tiếp cận đơn giản nhất để căn chỉnh văn bản (được vẽ bằng nhiều phông chữ khác nhau) dọc theo đường cơ sở chung là gì?
Hello, I am George.
------------------------------ <- all text aligns to a common baseline
^ ^ ^
| | |
Courier Arial Times <- font used for a particular bit of text
20pt 40pt 30pt
Vì tôi không tìm thấy bất kỳ chức năng GDI + nào để thực hiện việc này trực tiếp, tôi đã đưa ra phương pháp riêng của mình (được nêu bên dưới). Tuy nhiên:
Tôi tự hỏi có thực sự không phải là cách dễ dàng hơn để hoàn thành công việc này không?
cách tiếp cận hiện tại của tôi:
1) Thu thập một danh sách tất cả System.Drawing.Font
s sẽ được sử dụng để vẽ văn bản.
2) Đối với mỗi Font
, tìm ra vị trí thẳng đứng của đường cơ sở tính theo pixel, sử dụng đoạn mã sau:
// variables used in code sample (already set)
Graphics G;
Font font;
...
// compute ratio in order to convert from font design units to pixels:
var designUnitsPerPixel = font.GetHeight(G)/
font.FontFamily.GetLineSpacing(font.Style);
// get the cell ascent (baseline) position in design units:
var cellAscentInDesignUnits = font.FontFamily.GetCellAscent(font.Style);
// finally, convert the baseline position to pixels:
var baseLineInPixels = cellAscentInDesignUnits * designUnitsPerPixel;
3) Đối với tất cả Font
s sử dụng, xác định giá trị lớn nhất baseLineInPixels
như được tính ở trên và lưu trữ giá trị này thành maxBaseLineInPixels
.
4) Vẽ mỗi bit của văn bản trong cách thức sau đây:
// variables used in code sample (already set):
Graphics G;
Font font;
string text;
...
// find out how much space is needed for drawing the text
var measureF = G.MeasureString(text, font);
// determine location where text will be drawn:
var layoutRectF = new RectangleF(new PointF(0f, 0f), measureF);
layoutRectF.Y += maxBaseLineInPixels - baseLineInPixels;
//^the latter value 'baseLineInPixels' is specific to the font used
// draw text at specified location
G.DrawString(text, font, Brushed.Black, layoutRectF);
Tôi có thiếu cái gì đó, hoặc là có thực sự không có cách nào dễ dàng hơn?
Đã trải qua ngày hôm nay và hôm qua. Dường như là giải pháp duy nhất. Lưu ý rằng Font.GetHeight (Graphics) sẽ trả về giá trị trong PageUnit của đối tượng Graphics, thay vì theo pixel. Tôi đang sử dụng giải pháp của Bob Powell (http://www.bobpowell.net/formattingtext.htm) ngay bây giờ, bằng cách sử dụng khối mã cuối cùng trong bài viết của mình (tốt, trong C#), và chuyển đổi thành mm, vì tôi cần điều này cho một thói quen tạo bản vẽ/in/bản vẽ được chia sẻ. – OregonGhost
Cảm ơn phản hồi của bạn. Tôi cảm thấy nhẹ nhõm khi nghe (vâng ... :) rằng vẽ văn bản với GDI + thực sự * là * phức tạp và tôi không chỉ tưởng tượng ra điều này. Tôi đã quyết định từ bỏ vấn đề này và tiếp tục tới WPF (nơi GDI + không còn quan trọng và mọi thứ hy vọng sẽ dễ dàng hơn một chút). – stakx