代码之家  ›  专栏  ›  技术社区  ›  Stephen Curial

使用可变宽度字体创建文本列

  •  4
  • Stephen Curial  · 技术社区  · 17 年前

    我正在尝试为将在MSN Messenger上运行的C#应用程序创建文本栏。我很难把所有东西都排好。

    下面是我想要的输出示例:

    1)  Pizza Hut                                            123 Fake St.
    2)  Domino's Pizza                                       123 Fake St.
    3)  The Cheesecake Cafe                                  123 Fake St.
    4)  Capital Pizza & Steakhouse                           123 Fake St.
    5)  Funky Pickle Pizza                                   123 Fake St.
    6)  Boston Pizza                                         123 Fake St.
    7)  Rose Bowl Rouge Lounge                               123 Fake St.
    8)  Royal Pizza                                          123 Fake St.
    9)  A Columbus Pizza & Donair Inc                        123 Fake St.
    

    但由于它是一种可变宽度字体,因此显示如下:

    1)  Pizza Hut                                        123 Fake St.
    2)  Domino's Pizza                                   123 Fake St.
    3)  The Cheesecake Cafe                                  123 Fake St.
    4)  Capital Pizza & Steakhouse                               123 Fake St.
    5)  Funky Pickle Pizza                                   123 Fake St.
    6)  Boston Pizza                                     123 Fake St.
    7)  Rose Bowl Rouge Lounge                               123 Fake St.
    8)  Royal Pizza                                          123 Fake St.
    9)  A Columbus Pizza & Donair Inc                    123 Fake St.
    

    我尝试过使用C#string.PadRight()函数,也尝试过创建自己的函数,使用空格和制表符添加填充。两者都适用于固定宽度字体,但也适用于可变宽度字体。

    有没有办法确定给定字体中字符串的宽度?

    或者有人有其他建议吗?

    4 回复  |  直到 17 年前
        1
  •  7
  •   Julien Roncaglia    16 年前

    只要使用 TextRenderer 班最简单的情况是:

    Size size = TextRenderer.MeasureText("Hello world", someFont);
    

    如果您无权访问System.Windows.Fonts Graphics.MeasureString 尽管如此,它仍有一些局限性,但应该做到:

    Bitmap bmp = new Bitmap(1,1);
    Graphics graphics = Graphics.FromImage(bmp);
    SizeF size = graphics.MeasureString("Hello world", someFont);
    

    但是请注意,如果文本的字体和空格必须相同,则会出现无法完全对齐文本的情况。我不知道MSN Messenger在您的情况下能做些什么,但除非您能够访问至少一部分HTML,否则您将无法获得完美的输出。

    您还应该意识到,如果您在本地计算机上进行测量,并且发送到另一台计算机时没有安装正确的字体,那么您的列将不再像列,因此您的列仅限于所有计算机上显示的基本字体子集。

    如果多个操作系统支持也是一项要求,那么您将遇到一些大问题,因为Mac和PC上的Arial字体看起来(和尺寸)并不完全相同。

        2
  •  0
  •   CodeMonkey1313    17 年前

    您可以尝试使用Graphics类测量给定特定字体的字符串长度,然后使用该长度确定要使用的选项卡数。

        3
  •  0
  •   Chris McElligott Park    17 年前

    看起来您正试图在单个文本字段中以ASCII格式呈现这一切。对如果是这样,那就相当棘手了。看起来现在每个标签后面都有固定数量的标签,这就是问题所在。您可以改为使用空格——我怀疑您正在使用padright(不太熟悉该特定函数)执行此操作。

    然而,关键的是,如果使用那样的纯ASCII,以可变宽度字体显示,您将永远无法在第二列中完全对齐。如果你努力的话,你可以接近它,但就是这样——如果你有一行有很多大写字母W,另一行有很多小写字母i,无论你做什么,你都会有很大的宽度差异。如果使用GDI进行渲染,最好的方法是每列调用一次DrawText。如果需要,可以从每列中生成一个大字符串,并在第一列上调用MeasureString来确定第二列需要移动多少空间。

    或者,如果这是一个可以执行html的界面,那么表或div将非常有用。取决于您环境的具体情况。如果这是WinForms,您还可以在FlowLayout面板中设置两个自动高度设置标签,等等。有很多选项可以实现这一点,但不是使用可变宽度字体的纯ascii。

    编辑:另外,我看到您询问如何在web服务中获取图形类实例。您可以这样做:

        private static Bitmap bitmap = new Bitmap( 1, 1 );
        private static Graphics graphics = null;
    
        public static Graphics GetGeneralGraphics()
        {
            if ( graphics == null )
                graphics = Graphics.FromImage( bitmap );
            return graphics;
        }
    

    您可能希望在web服务上下文中生成这些局部变量(完成后正确处理)。

        4
  •  -1
  •   Andrew    17 年前

    推荐文章