使用GDI +,什么是对齐文本的最简单的方法(在几个不同的字体画),以及一个共同的基准? [英] Using GDI+, what's the easiest approach to align text (drawn in several different fonts) along a common baseline?

查看:520
本文介绍了使用GDI +,什么是对齐文本的最简单的方法(在几个不同的字体画),以及一个共同的基准?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在上在同一行显示文本块(每一个潜在的不同的字体)一个自定义用户控件。我想对齐文本的所有位的完全的沿着一个共同的基准。例如:

I'm currently working on a custom user control which displays pieces of text (each with a potentially different font) on one line. I'd like to align all those bits of text exactly along a common baseline. For example:

  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

由于我没有找到任何GDI +功能直接做到这一点,我来到了我自己的方法(如下所述)。但是:

Because I haven't found any GDI+ functionality to do this directly, I came up with my own method (outlined below). However:

不知是不是真的有一个简单的方法来完成这件事?

I wonder if there really isn't an easier way to get this done?

1)收集所有的列表 System.Drawing.Font s表示将用于绘制文本。

1) Gather a list of all System.Drawing.Fonts that will be used for drawing text.

2)对于每个字体,找到像素基线的垂直位置,使用下面的code:

2) For each Font, find the vertical position of the baseline in pixels, using the following 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)对于所有字体被使用过,确定最大 baseLineInPixels 值上面的计算和存储这些值 maxBaseLineInPixels

3) For all Fonts used, determine the maximum baseLineInPixels value as computed above and store this value to maxBaseLineInPixels.

4)画出通过以下方式文本的每一位:

4) Draw each bit of text in the following manner:

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

我缺少的东西,或者是真的没有更简单的方法?

Am I missing something, or is there really no easier way?

推荐答案

我已经研究了同样的事情在过去的几天里,我终于找到了答案的 formattingtext.aspx相对=nofollow>。这code(在文章的底部)的工作对我很好,希望可以帮助其他人解决这个问题挣扎:

I've been researching the same thing for the last few days, and I finally found an answer on this blog page. This code (at the bottom of the article) worked really well for me and hopefully helps anyone else struggling with this problem:

private void DrawOnBaseline(string s, Graphics g, Font f, Brush b, Point pos)
    {
      float baselineOffset=f.SizeInPoints/f.FontFamily.GetEmHeight(f.Style)*f.FontFamily.GetCellAscent(f.Style);
      float baselineOffsetPixels = g.DpiY/72f*baselineOffset;

      g.DrawString(s,f,b,new Point(pos.X,pos.Y-(int)(baselineOffsetPixels+0.5f)),StringFormat.GenericTypographic);
    }

这篇关于使用GDI +,什么是对齐文本的最简单的方法(在几个不同的字体画),以及一个共同的基准?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆