<p>I'm using the .NETCF (Windows Mobile) <code>Graphics</code> class and the <code>DrawString()</code> method to render a single character to the screen.</p>

<p>The problem is that I can't seem to get it centred properly. No matter what I set for the Y coordinate of the location of the string render, it always comes out lower than that and the larger the text size the greater the Y offset.</p>

<p>For example, at text size 12, the offset is about 4, but at 32 the offset is about 10.</p>

<p>I want the character to vertically take up most of the rectangle it's being drawn in and be centred horizontally. Here's my basic code. <code>this</code> is referencing the user control it's being drawn in.</p>

<pre><code>Graphics g = this.CreateGraphics();

float padx = ((float)this.Size.Width) * (0.05F);
float pady = ((float)this.Size.Height) * (0.05F);

float width = ((float)this.Size.Width) - 2 * padx;
float height = ((float)this.Size.Height) - 2 * pady;

float emSize = height;

g.DrawString(letter, new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular),
            new SolidBrush(Color.Black), padx, pady);
</code></pre>

<p>Yes, I know there is the label control that I could use instead and set the centring with that, but I actually do need to do this manually with the <code>Graphics</code> class.</p>

[{'answer_id': 8010, 'author': 'John', 'author_id': 33, 'author_profile': 'https://Stackoverflow.com/users/33', 'pm_score': 2, 'selected': False, 'text': '<p>You can use an instance of the <code>StringFormat</code> object passed into the <code>DrawString</code> method to center the text.</p>\n\n<p>See <a href="http://msdn.microsoft.com/en-us/library/21kdfbzs.aspx" rel="nofollow noreferrer">Graphics.DrawString Method</a> and <a href="http://msdn.microsoft.com/en-us/library/system.drawing.stringformat.aspx" rel="nofollow noreferrer">StringFormat Class</a>.</p>\n'}, {'answer_id': 8013, 'author': 'TheSmurf', 'author_id': 1975282, 'author_profile': 'https://Stackoverflow.com/users/1975282', 'pm_score': 3, 'selected': False, 'text': '<p>Here\'s some code. This assumes you are doing this on a form, or a UserControl.</p>\n\n<pre><code>Graphics g = this.CreateGraphics();\nSizeF size = g.MeasureString("string to measure");\n\nint nLeft = Convert.ToInt32((this.ClientRectangle.Width / 2) - (size.Width / 2));\nint nTop = Convert.ToInt32((this.ClientRectangle.Height / 2) - (size.Height / 2));\n</code></pre>\n\n<p>From your post, it sounds like the ClientRectangle part (as in, you\'re not using it) is what\'s giving you difficulty.</p>\n'}, {'answer_id': 8056, 'author': 'dbkk', 'author_id': 838, 'author_profile': 'https://Stackoverflow.com/users/838', 'pm_score': 4, 'selected': False, 'text': '<p>To draw a centered text:</p>\n\n<pre><code>TextRenderer.DrawText(g, "my text", Font, Bounds, ForeColor, BackColor, \n  TextFormatFlags.HorizontalCenter | \n  TextFormatFlags.VerticalCenter |\n  TextFormatFlags.GlyphOverhangPadding);\n</code></pre>\n\n<p>Determining optimal font size to fill an area is a bit more difficult. One working soultion I found is trial-and-error: start with a big font, then repeatedly measure the string and shrink the font until it fits. </p>\n\n<pre><code>Font FindBestFitFont(Graphics g, String text, Font font, \n  Size proposedSize, TextFormatFlags flags)\n{ \n  // Compute actual size, shrink if needed\n  while (true)\n  {\n    Size size = TextRenderer.MeasureText(g, text, font, proposedSize, flags);\n\n    // It fits, back out\n    if ( size.Height &lt;= proposedSize.Height &amp;&amp; \n         size.Width &lt;= proposedSize.Width) { return font; }\n\n    // Try a smaller font (90% of old size)\n    Font oldFont = font;\n    font = new Font(font.FontFamily, (float)(font.Size * .9)); \n    oldFont.Dispose();\n  }\n}\n</code></pre>\n\n<p>You\'d use this as:</p>\n\n<pre><code>Font bestFitFont = FindBestFitFont(g, text, someBigFont, sizeToFitIn, flags);\n// Then do your drawing using the bestFitFont\n// Don\'t forget to dispose the font (if/when needed)\n</code></pre>\n'}, {'answer_id': 8097, 'author': 'Adam Haile', 'author_id': 194, 'author_profile': 'https://Stackoverflow.com/users/194', 'pm_score': 6, 'selected': True, 'text': "<p>Through a combination of the suggestions I got, I came up with this:</p>\n\n<pre><code>    private void DrawLetter()\n    {\n        Graphics g = this.CreateGraphics();\n\n        float width = ((float)this.ClientRectangle.Width);\n        float height = ((float)this.ClientRectangle.Width);\n\n        float emSize = height;\n\n        Font font = new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular);\n\n        font = FindBestFitFont(g, letter.ToString(), font, this.ClientRectangle.Size);\n\n        SizeF size = g.MeasureString(letter.ToString(), font);\n        g.DrawString(letter, font, new SolidBrush(Color.Black), (width-size.Width)/2, 0);\n\n    }\n\n    private Font FindBestFitFont(Graphics g, String text, Font font, Size proposedSize)\n    {\n        // Compute actual size, shrink if needed\n        while (true)\n        {\n            SizeF size = g.MeasureString(text, font);\n\n            // It fits, back out\n            if (size.Height &lt;= proposedSize.Height &amp;&amp;\n                 size.Width &lt;= proposedSize.Width) { return font; }\n\n            // Try a smaller font (90% of old size)\n            Font oldFont = font;\n            font = new Font(font.Name, (float)(font.Size * .9), font.Style);\n            oldFont.Dispose();\n        }\n    }\n</code></pre>\n\n<p>So far, this works flawlessly.</p>\n\n<p>The only thing I would change is to move the FindBestFitFont() call to the OnResize() event so that I'm not calling it every time I draw a letter.  It only needs to be called when the control size changes.  I just included it in the function for completeness.</p>\n"}, {'answer_id': 26498, 'author': 'Quibblesome', 'author_id': 1143, 'author_profile': 'https://Stackoverflow.com/users/1143', 'pm_score': 7, 'selected': False, 'text': '<p>I\'d like to add another vote for the StringFormat object.\nYou can use this simply to specify "center, center" and the text will be drawn centrally in the rectangle or points provided:</p>\n\n<pre><code>StringFormat format = new StringFormat();\nformat.LineAlignment = StringAlignment.Center;\nformat.Alignment = StringAlignment.Center;\n</code></pre>\n\n<p>However there is one issue with this in CF. If you use Center for both values then it turns TextWrapping off. No idea why this happens, it appears to be a bug with the CF.</p>\n'}, {'answer_id': 197551, 'author': 'Chris Hughes', 'author_id': 27405, 'author_profile': 'https://Stackoverflow.com/users/27405', 'pm_score': 6, 'selected': False, 'text': '<p>To align a text use the following:</p>\n\n<pre><code>StringFormat sf = new StringFormat();\nsf.LineAlignment = StringAlignment.Center;\nsf.Alignment = StringAlignment.Center;\ne.Graphics.DrawString("My String", this.Font, Brushes.Black, ClientRectangle, sf);\n</code></pre>\n\n<p>Please note that the text here is aligned in the given bounds. In this sample this is the ClientRectangle. </p>\n'}]
['https://Stackoverflow.com/questions/7991', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/194/']