Przy użyciu GDI +, jakie jest najłatwiejsze podejście do wyrównania tekstu (narysowanego kilkoma różnymi czcionkami) wzdłuż wspólnej linii bazowej?

Mój problem:

Obecnie pracuję nad niestandardową kontrolką użytkownika, która wyświetla fragmenty tekstu (każdy z potencjalnie inną czcionką) w jednym wierszu. Chciałbym wyrównać wszystkie te fragmenty tekstudokładnie wzdłuż wspólnej linii bazowej. Na przykład:

  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

Ponieważ nie znalazłem żadnej funkcji GDI +, aby to zrobić bezpośrednio, wymyśliłem własną metodę (opisaną poniżej). Jednak:

Zastanawiam się, czy naprawdę nie ma łatwiejszego sposobu, aby to zrobić?

Moje obecne podejście:

1) Zbierz listę wszystkichSystem.Drawing.Fonts, które będą używane do rysowania tekstu.

2) Dla każdegoFont, znajdź pionową pozycję linii bazowej w pikselach, używając następującego kodu:

// 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) Dla wszystkichFontużywane, określ maksimumbaseLineInPixels wartość obliczona powyżej i zapisz tę wartośćmaxBaseLineInPixels.

4) Narysuj każdy bit tekstu w następujący sposób:

// 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);

Czy czegoś mi brakuje, czy naprawdę nie ma łatwiejszego sposobu?

questionAnswers(2)

yourAnswerToTheQuestion