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

发布于 2024-07-14 05:53:24 字数 1575 浏览 7 评论 0原文

我正在尝试为将在 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() 函数以及创建我自己的函数,使用空格和制表符添加填充。 两者都适用于固定宽度字体,但适用于可变宽度字体。

有什么方法可以确定给定字体中字符串的宽度吗?

或者有人有其他建议吗?

I'm trying to create coloumns of text for a C# app that will be running on MSN Messenger. I'm having trouple getting everything to line up.

Here's an example of the output that I want:

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.

But because it is a variable width font it is displaying like this:

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.

I have tried using the C# string.PadRight() function as well as creating my own function that add padding using spaces and tabs. Both work fine with fixed width fonts but break with variable width fonts.

Is there any way to determine the width of a string in a given font?

Or does anyone have any other suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

和影子一齐双人舞 2024-07-21 05:53:24

只需使用 TextRenderer 类。 最简单的情况:

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

如果您无权访问 System.Windows.Fonts 图形.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 字体看起来(和测量)并不完全相同。

Just use the TextRenderer class. The simplest case :

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

If you don't have access to System.Windows.Fonts Graphics.MeasureString remains, it have some limitations but should do the work :

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

But be aware that if the font of your text and the spaces MUST be the same there will be cases where you can't align the text perfectly. I don't know what MSN Messenger is able to do in your case but except if you have access to at least a subset of HTML you won't have a perfect output.

You should also be aware that if you do measurements on a local computer and send to another without the correct font installed your columns won't look like columns anymore so your are limited to the basic subset of fonts presents on all computers.

If multiple operating system support is also a requirement you will have some big problems as the Arial font on Mac and PCs doesn't look (and measure) exactly the same.

寄人书 2024-07-21 05:53:24

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

You could try using the Graphics class to measure the length of the string given a specific font, then use that to determine how many tabs to use.

若无相欠,怎会相见 2024-07-21 05:53:24

看起来您正在尝试在单个文本字段中以 ASCII 格式呈现所有内容。 是的? 如果是这样的话,那就相当棘手了。 看起来现在每个选项卡后面都有固定数量的选项卡,这就是问题所在。 你可以改为做空格——我怀疑你正在用 padright 做(不太熟悉该特定功能)。

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

或者,如果这是一个可以处理 html、表格或 div 的界面,那就太好了。 取决于您的环境的具体情况。 您还可以做一些事情,例如在 FlowLayout 面板中添加两个自动高度设置标签(如果这是 WinForms 等)。有很多选项可以实现此功能,但不仅仅是具有可变宽度字体的纯 ascii。

编辑:另外,我看到您询问如何在 Web 服务中获取 Graphics 类实例。 您可以执行以下操作:

    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 服务上下文中创建这些局部变量(完成后正确处置)。

It looks like you are trying to render this all in ASCII in a single text field. Yes? If that's the case, that's pretty tricky. It looks like you have a fixed number of tabs after each one right now, and that would be the issue. You could instead do spaces -- which I suspect you are doing with padright (not very familiar with that specific function).

The key thing, though, is that with pure ASCII like that, shown in a variable width font, you will never get it to line up perfectly in a second column. You can get it close if you are diligent, but that's it -- if you have one row with a lot of capital W's, and another with a lot of lowercase i's, you'll have big width differences no matter what you do. If you're rendering in GDI, the best approach is to make one call to DrawText per column. You can make one big string out of each column if you want, and call MeasureString on the first column to determine how much space you need to move over for the second column.

Or if this is an interface where you can do html, tables or divs would work great. Depends on the specifics of your environment. You could also do something like having two auto-height-set labels in a FlowLayout panel if this was WinForms, etc. There are a lot of options for making this work, but just not pure ascii with a variable width font.

EDIT: Also, I saw you asked about how to get a Graphics class instance in a web service. You can do something like this:

    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;
    }

You probably want to make those local variables (that you properly dispose when finished with) in a web services context.

原野 2024-07-21 05:53:24

您可能应该将所有内容格式化为 HTML,然后您可以只输出列的 TABLE 和 TR/TD 元素

You should probably format everything in HTML, then you could just output TABLE and TR/TD elements for the columns

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文