Was ist mit GDI + die einfachste Methode, um Text (in mehreren verschiedenen Schriftarten) entlang einer gemeinsamen Grundlinie auszurichten?
Ich arbeite derzeit an einem benutzerdefinierten Benutzersteuerelement, das Textteile (jeweils mit einer möglicherweise anderen Schriftart) in einer Zeile anzeigt. Ich möchte all diese Textteile ausrichtengenau entlang einer gemeinsamen Grundlinie. Zum Beispiel:
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
Da ich keine GDI + -Funktionalität gefunden habe, die dies direkt ermöglicht, habe ich eine eigene Methode entwickelt (siehe unten). Jedoch:
Ich frage mich, ob es wirklich keinen einfacheren Weg gibt, dies zu erreichen.
Mein aktueller Ansatz:1) Sammeln Sie eine Liste allerSystem.Drawing.Font
s, die zum Zeichnen von Text verwendet werden.
2) Für jedenFont
finden Sie die vertikale Position der Grundlinie in Pixel mit dem folgenden Code:
// 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) Für alleFont
s verwendet, bestimmen Sie das MaximumbaseLineInPixels
Wert wie oben berechnet und speichern Sie diesen Wert inmaxBaseLineInPixels
.
4) Zeichnen Sie jedes Textstück auf folgende Weise:
// 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);
Vermisse ich etwas oder gibt es wirklich keinen einfacheren Weg?