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?
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.
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.
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.
You should probably format everything in HTML, then you could just output TABLE and TR/TD elements for the columns
来源:https://stackoverflow.com/questions/604298/creating-columns-of-text-with-a-variable-width-font