WPF definition of FontSize - c#

I know that in WPF, FontSize = 1/96 of an inch (same as 1 pixel I think). Is the FontSize dimension the height, the width, or diagonal size of a character? I would guess it's the font height, but the Microsoft documentation doesn't really indicate what it is.
Also, is there an easy way to get the height and width of a font size?
Answer:
So it looks like the FontSize is the height, and the width can only be determined (without knowing the actual character) on monospaced fonts since proportional fonts have varying widths.

They are referring to Font Size as used in Typefaces for Typography.
You can read about it here: Wikipedia: Typeface
The size of typefaces and fonts is traditionally measured in points;2 point has been defined differently at different times, but now the most popular is the Desktop Publishing point of 1⁄72 in (0.0139 in/0.35 mm). When specified in typographic sizes (points, kyus), the height of an em-square, an invisible box which is typically a bit larger than the distance from the tallest ascender to the lowest descender, is scaled to equal the specified size.[3] For example, when setting Helvetica at 12 point, the em square defined in the Helvetica font is scaled to 12 points or 1⁄6 in (0.17 in/4.3 mm). Yet no particular element of 12-point Helvetica need measure exactly 12 points.
A note...72 as stated in this Wikipedia article is what WinForms used. WPF switched to 96.
As for the second part of your question, I found this resource from an MSDN Link:
FormattedText formattedText = new FormattedText(
textBox1.Text.Substring(0, 1),
CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface(textBox1.FontFamily.ToString()),
textBox1.FontSize,
Brushes.Black
);
... formattedText.WidthIncludingTrailingWhitespace;
... formattedText.Height;

Related

How to obtain DPI equivalent of an adjustable column with no text in OpenXML

I would like to ask what units does column.width return when using Openxml? (IS it in EMU, metres, cm or dpi and how do i get its DPI equivalent?
From SpreadsheetOpenXmlFromScratch:
Note that the width of the digits depends on the font and the font size used. I'll be using the MeasureString() function of the Graphics class to measure pixel width.
Everything Vincent does is based on the font type and size. You will have to retrieve the font type and font size to run through the calculations.
EDIT: pp 40-50
No, it is using the font measurements, not the column text. Another excerpt:
Note that the width of the digits depends on the font and the font size used. I'll be using the MeasureString() function of the Graphics class to measure pixel width.
System.Drawing.Font drawfont = new System.Drawing.Font("Calibri", 11, FontStyle.Regular);
// I just need a Graphics object. Any reasonable bitmap size will do.
Graphics g = Graphics.FromImage(new Bitmap(256, 256));
Dim drawfont As New System.Drawing.Font("Calibri", 11, FontStyle.Regular)
' I just need a Graphics object. Any reasonable bitmap size will do.
Dim g As Graphics = Graphics.FromImage(New Bitmap(256, 256))
The font used should be the same as that used in your stylesheet. Otherwise you would be measuring for one font or font size, but using another font or font size to render your actual text in the Excel cell. I know it's obvious, but it's important to state here.
Specifically, it should be the font used in the Normal style. That word is capitalised for a reason. It refers to the cell style named Normal (together with "Good", "Bad" and "Neutral"). Get your friendly neighbourhood Excel geek to help you find the cell style option in Excel.
Some of his other methods do require text when he actually measures the width of a zero flanked by two underscores, then subtracts the width of the underscores to get a more accurate width, but this just requires the font name and style.
Now the MeasureString() function has a tiny problem. This is from the official documentation:
The MeasureString method is designed for use with individual strings and includes a small amount of extra space before and after the string to allow for overhanging glyphs.
What this means is that the following code will not exactly give you the pixel width of "0":
fWidthOfZero = (double)g.MeasureString("0", drawfont).Width;
fWidthOfZero = Convert.ToDouble(g.MeasureString("0", drawfont).Width)
Give it a try.

What is Rectangle width and height unit ? is it in pixels?

I want to know that System.Drawing.Rectangle has its width and height in pixels or not ?
My printer paper width is more than the rectangle area width, still the paper does not accomodate the rectangle area. The printer paper width is in pixels, so I think If I can convert rectangle width to pixels than I can exactly find out that rectangle width is more than paper or not and can adjust rectangle according to that.
The website http://bytes.com/topic/c-sharp/answers/715228-system-drawing-size-unit
has this to say about the unit of measurement used in system.drawing
Peter Duniho Gidi wrote: what is the unit of System.Drawing.Size?
when i'm writing Size = (1024,784), is it pixel? or something else? It
depends on the context. For Control properties (Size, Bounds,
ClientRectangle, etc), it's pixels. But for drawing, when the Size is
passed to something operating on a Graphics object, the Size is
interpreted according to the PageUnit property of that Graphics
object. So it could be any of the units found in the GraphicsUnit
enumeration except World, in that case.
Note of course also that a Graphics can have a transformation applied
to it, so any drawing using a Size is also affected by that. If the
PageUnit is Pixels, but you've got a 50% scaling factor applied, then
any Size you pass to a Graphics object winds up being in half-pixels
rather than whole pixels.
All the above is true for the Point struct too.
Secondly, you mentioned that you want to convert pixels. This website convert-me.com
has any unit you can imagine to convert to. The link I put will take you to the distance and length section where you can convert to and from pixels.
The Width and Height properties for System.Drawing.Rectangle are both in pixels. Here is the documentation for Height and Width:
The default unit is pixels.

C# calculate the height of a string in with the given width

Im trying to write text in C# so that it spans the required width (approximately).
To write text you need to specify the height. So I need to know what height would make it write to the desired length.
Font myFont = new Font(FontFamily.GenericSansSerif, unknown);
gc.DrawString(LabelText, myFont, gBrush, 0, 0);
Ive found the following, but it requires FONT, which requires height. Which defeats the whole point?
gc.MeasureString(LabelText, new Font(FontFamily.GenericSansSerif, 12), length);
How would I determine the required height to make for example "I am a String" stretch 50px.
There is an example on the site switchonthecode (note - archived version). They provide a method that takes a minimum and maximum font size along with the size of your area. It tries the minimum size and from there determines the ratio of the font and then determines the best size for you.

Strange behavior of graphics.MeasureString at different resolutions

I have noticed strange behavior of Graphics.MeasureString at different resolutions.
For the default resolution (96x96) there is a linear relationship across the different font sizes I tested.
However, if I raise it to 512 x 512, the linear relationship disappears and something really strange happens when using measure string. (See 4 plots below)
If I leave the resolution at the default size for a graphics object, and measure the font size, here is the relationship between font size and the width of a string:
Graphics object, Default Resolution (96):
Font size (X-Axis), WIDTH of a particular string (Y-Axis)
Font size (X-Axis), HEIGHT of a particular string (Y-Axis)
However, if I change the resolution
Graphics object, 512 resolution:
Font size (X-Axis), WIDTH of a particular string (Y-Axis)
Font size (X-Axis), HEIGHT of a particular string (Y-Axis)
Anyone know why this might be happening?
Thanks you.
It should noted that I am using .NET 4 (Full Profile)
Code used to generate graphs (Change resolution for each type):
string str = "6 CN-3 Tie EomgVeo405- 2ss>era09rni IBne 20iopv Atdrsn - Ng72";
SizeF sizef = new SizeF(855, 14.000001f);
StringFormat stringFormat = new StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Near,
Trimming = StringTrimming.None,
FormatFlags = StringFormatFlags.NoClip,
};
Bitmap b = new Bitmap(901, 401);
//b.SetResolution(512, 512);
Graphics g = Graphics.FromImage(b);
for (float x = origFont.Size; x >= 0.5; x -= 0.1f)
{
var data = g.MeasureString(str, new Font("Microsoft Sans Serif", x), sizef, stringFormat);
Console.WriteLine(x + "\t" + data.Width + "\t" + data.Height);
}
This answer is a guess, but the evidence fits it perfectly.
What you're seeing is the string being wrapped onto two lines.
Let's assume the following:
The width of the text is linearly proportional to the fontsize
The height of the text is linearly proportional to the fontsize
This fits the start of your 512-resolution graph, everything increases linearly.
At some point, the width is sharply reduced by a certain amount, and at the same time the height doubles.
This means that a word was moved onto line 2, which doubled the height (2 lines vs. 1 before), and the string got a certain amount less wide since the last word on the line is now on the start of line 2.
From there on, the width slowly increases again as the part of the string still on line 1 linearly gets wider as the font-size increases. At the same time the height increases linearly, but now at double the rate as before the break, since 2 lines now get higher, vs. 1 before.
At some point, again, the last word on line 1 breaks the maximum width and is moved down on line 2, before the word that was previously alone there, and at that point, the width is again sharply reduced by a certain amount.
If you were to continue your graph, I predict that the width will continue its current pattern. The exact amount it dips down each time is proportional to the width of the word being moved. At the same time, at some point the 2nd line will need to be broken, in which case you get a 3x height and the height will then increase at 3x the pace, and so on.
I believe this might be happening because of the hinting/grid fitting algorithms in GDI+. Font sizes in your tests are extremely small in terms of glyph legibility, and, because of that, the rendering engine tries to apply special transformations to each glyph to make it clearer. These transformations depend greatly on the target DPI.
It is also worth mentioning that major increase of the font size will lead to a more 'linear' dependency.
This article explains these mechanisms in more details with some examples.
Meanwhile, you can try to modify the Graphics.TextRenderingHint property and/or try TextRenderer instead of Graphics.DrawString if that will help you with your issue.

How to Adjust the Text Size according to image size while Drawing String on an Image in C#

I'm using the Drawstring method of the Graphics Class to Draw a Text on an Image.The Font is Specified before drawing.
G.DrawString(mytext, font, brush, 0, 0)
The Problem arises when the same text is drawn on an image with smaller size.The Text drawn appears to be larger.I'm looking for a solution to alter the font size according to the image size so that the text don't appear larger or smaller when drawn on images of different sizes.
I'm attaching the images with different sizes with the text of same font size drawn on it.
http://i.stack.imgur.com/ZShUI.jpg
http://i.stack.imgur.com/GUfbM.jpg
I can't directly post the image because I'm not allowed.
You would get most precise scaling by drawing on separate image and then slapping that image onto original one. You'd do that as follows:
Create in-memory Bitmap with enough space
Draw text on that bitmap in your default font
Draw image containing the text onto original image by scaling it to size you need
Code:
Bitmap textBmp = new Bitmap(100, 100);
Graphics textBmpG = Graphics.FromImage(textBmp);
textBmpG .DrawString("test 1", new Font(FontFamily.GenericSansSerif, 16), Brushes.Red, new PointF(0, 0));
Graphics origImgG = Graphics.FromImage(originalImg);
origImgG.DrawImage(textBmpG, new Rectangle(50, 50, 50, 50), new Rectangle(0, 0, 100, 100), GraphicsUnit.Pixel);
Take notice of last line and Rectangle parameters. Use them to scale your text bitmap onto original image. Alternatively, you can also choose Graphics.MeasureString method to determine how wide your text would be and make attempts until you get best one you can.
Use Graphics.MeasureString() to measure how big your string would be on the image
Decrease/increase font step by step accordingly
As you requested in comment I'll give you more detailed suggestion here. Say your original image width is WI1, and width of text on it using Graphics.MeasureString is WT1. If you resize your image to width WI2, then your perfect text width would be WT2 = WT1 * WI2 / WI1. Using DrawText method you may not be able to get this exact width because when you increase font by 1 it may jump over that value. So you have to make several attempts and find best. Pick a size of font, if resulting text width is smaller (measure with MeasureString), increase it until it becomes bigger than target and you've got about closest match. Same thing goes if it's too big. Decrease font step by step.
This is quick and dirty as you see, because you have many draws, but I can't think of better solution, unless you're using monospaced fonts.
Difference between those solutions would be that in first you can get text to fit EXACT size you need, but you probably would loose some font readability due to scaling. Second solution would give good readability, but you can't get pixel perfect size of text.
In my opinion you have two ways:
Draw text on original image and then resize resulting image (so, even text included in it)
Scale font size by a factor newImageWidth/originalImageWidth.
It's not perfect because you could have some problem with text height (if new image is not just scaled but with different aspect ratio), but it's an idea

Categories