HighTechTalks DotNet Forums  

Graphics.MeasureString? or Graphics.DrawString?

Dotnet Framework (Drawing) microsoft.public.dotnet.framework.drawing


Discuss Graphics.MeasureString? or Graphics.DrawString? in the Dotnet Framework (Drawing) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Norman Diamond
 
Posts: n/a

Default Graphics.MeasureString? or Graphics.DrawString? - 12-16-2007 , 09:05 PM






In Windows XP, the following code figures out where to position a string and
draws the string. In Vista, the following code figures out where to
position all except the last character of the string and draws all except
the last character of the string.

Notice that this legend is located near the lower left of the chart and
there's lots of blank space on the right. (In fact after all that blank
space there's another legend at the lower right which suffers from exactly
the same defect, but I'm omitting that code because the positioning might
lead to a red herring. Anyway there's lots and lots of blank space where
there should be the last character and lots and lots of blank space.)

legendSize = m_grChartResults.MeasureString(legend, this.Font);
legendRectangle.X = ChartLeftMargin - (legendSize.Width / 2.0f);
if (legendRectangle.X < 0)
{
legendRectangle.X = 0;
}
legendRectangle.Width = legendSize.Width;
legendRectangle.Y = pbChartResults.Height - legendSize.Height - 2;
legendRectangle.Height = legendSize.Height;
m_grChartResults.DrawString(legend, legendFont, legendBrush,
legendRectangle);


DotNet Framework 2 with SP1, Visual Studio 2005 with SP1 C#.


Reply With Quote
  #2  
Old   
Bob Powell [MVP]
 
Posts: n/a

Default Re: Graphics.MeasureString? or Graphics.DrawString? - 12-17-2007 , 03:33 AM






The text rendering hint of the Graphics device you use to measure with and
the font settings themselves may have a bearing on the measurement. Some
fonts incorrectly report their sizes and errors can reult when measuring.

--
--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.


"Norman Diamond" <ndiamond (AT) community (DOT) nospam> wrote

Quote:
In Windows XP, the following code figures out where to position a string
and draws the string. In Vista, the following code figures out where to
position all except the last character of the string and draws all except
the last character of the string.

Notice that this legend is located near the lower left of the chart and
there's lots of blank space on the right. (In fact after all that blank
space there's another legend at the lower right which suffers from exactly
the same defect, but I'm omitting that code because the positioning might
lead to a red herring. Anyway there's lots and lots of blank space where
there should be the last character and lots and lots of blank space.)

legendSize = m_grChartResults.MeasureString(legend, this.Font);
legendRectangle.X = ChartLeftMargin - (legendSize.Width / 2.0f);
if (legendRectangle.X < 0)
{
legendRectangle.X = 0;
}
legendRectangle.Width = legendSize.Width;
legendRectangle.Y = pbChartResults.Height - legendSize.Height - 2;
legendRectangle.Height = legendSize.Height;
m_grChartResults.DrawString(legend, legendFont, legendBrush,
legendRectangle);


DotNet Framework 2 with SP1, Visual Studio 2005 with SP1 C#.


Reply With Quote
  #3  
Old   
Norman Diamond
 
Posts: n/a

Default Re: Graphics.MeasureString? or Graphics.DrawString? - 12-17-2007 , 06:20 PM



The program is written in C# and the font is MS UI Gothic, 9pt. I don't see
any font specification in the source code (including designers and resx
files), only in the properties window in Visual Studio 2005 SP1. I wonder
how the resource compiler and C# compiler know what the font is, even though
it's Visual Studio's default.

Anyway, the font is the same in both Windows XP and Vista. Do you think
maybe Vista's version of the MS UI Gothic font incorrectly reports its
sizes?

On a dual boot machine the graphics device is the same for both XP and
Vista, though the drivers aren't completely identical. Are string
measurements computed by the driver instead of by Windows internals?


"Bob Powell [MVP]" <bob (AT) spamkillerbobpowell (DOT) net> wrote

Quote:
The text rendering hint of the Graphics device you use to measure with and
the font settings themselves may have a bearing on the measurement. Some
fonts incorrectly report their sizes and errors can reult when measuring.

--
--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.


"Norman Diamond" <ndiamond (AT) community (DOT) nospam> wrote in message
news:%23KwI8mFQIHA.1164 (AT) TK2MSFTNGP02 (DOT) phx.gbl...
In Windows XP, the following code figures out where to position a string
and draws the string. In Vista, the following code figures out where to
position all except the last character of the string and draws all except
the last character of the string.

Notice that this legend is located near the lower left of the chart and
there's lots of blank space on the right. (In fact after all that blank
space there's another legend at the lower right which suffers from
exactly the same defect, but I'm omitting that code because the
positioning might lead to a red herring. Anyway there's lots and lots of
blank space where there should be the last character and lots and lots of
blank space.)

legendSize = m_grChartResults.MeasureString(legend, this.Font);
legendRectangle.X = ChartLeftMargin - (legendSize.Width / 2.0f);
if (legendRectangle.X < 0)
{
legendRectangle.X = 0;
}
legendRectangle.Width = legendSize.Width;
legendRectangle.Y = pbChartResults.Height - legendSize.Height - 2;
legendRectangle.Height = legendSize.Height;
m_grChartResults.DrawString(legend, legendFont, legendBrush,
legendRectangle);


DotNet Framework 2 with SP1, Visual Studio 2005 with SP1 C#.



Reply With Quote
  #4  
Old   
Ron
 
Posts: n/a

Default Re: Graphics.MeasureString? or Graphics.DrawString? - 12-20-2007 , 08:16 AM



Norman,
The measurements of the string depend on the StringFormat being used.
The default one includes a fair amount of space around the whole string when
measuring. For what you want to do one of the MeasureString calls including
a StringFormat would probably work best and include a clone of
StringFormat.GenericTypographic to get the closest meaurements around the
object being measured.
i.e. the following after you compute the starting point
legendSize = m_grChartResults.MeasureString(legend, this.Font,
new PointF(0, 0), StringFormat.GenericTypographic);
for a string at the top/left of the page. The starting location is used
because if there is some kind of non-linear transform done on the graphics
being used the size of the string depends on the location.

Ron Allen


"Norman Diamond" <ndiamond (AT) community (DOT) nospam> wrote

Quote:
In Windows XP, the following code figures out where to position a string
and draws the string. In Vista, the following code figures out where to
position all except the last character of the string and draws all except
the last character of the string.

Notice that this legend is located near the lower left of the chart and
there's lots of blank space on the right. (In fact after all that blank
space there's another legend at the lower right which suffers from exactly
the same defect, but I'm omitting that code because the positioning might
lead to a red herring. Anyway there's lots and lots of blank space where
there should be the last character and lots and lots of blank space.)

legendSize = m_grChartResults.MeasureString(legend, this.Font);
legendRectangle.X = ChartLeftMargin - (legendSize.Width / 2.0f);
if (legendRectangle.X < 0)
{
legendRectangle.X = 0;
}
legendRectangle.Width = legendSize.Width;
legendRectangle.Y = pbChartResults.Height - legendSize.Height - 2;
legendRectangle.Height = legendSize.Height;
m_grChartResults.DrawString(legend, legendFont, legendBrush,
legendRectangle);


DotNet Framework 2 with SP1, Visual Studio 2005 with SP1 C#.


Reply With Quote
  #5  
Old   
Norman Diamond
 
Posts: n/a

Default Re: Graphics.MeasureString? or Graphics.DrawString? - 12-20-2007 , 06:25 PM



I will try your suggestion, but meanwhile I'm trying to figure out why the
simplest form of MeasureString didn't already work that way.

You write:
Quote:
StringFormat.GenericTypographic to get the closest meaurements
Whereas MSDN says for the simplest version of MeasureString:
* includes a small amount of extra space before and after the string

Since the small amount of extra space in the simplest version was too small
in Vista (it was enough in XP), what default StringFormat was it using?

You also write:
Quote:
The starting location is used because if there is some kind of non-linear
transform done on the graphics being used the size of the string depends
on the location.
I'm not aware of any transform at all being done on the graphics. The form
has a PictureBox. I created a Bitmap of the same size as the PictureBox,
assigned that to the PictureBox's Image, created a Graphics for the Bitmap,
and drew to the Graphics. (This also seems overly cumbersome, but anything
less and I'd have to recompute every pixel in an OnPaint.) Anyway, as far
as I can tell, every pixel maps 1-to-1.

What kind of transform is being applied by default, and/or what is the
default starting point used by the simplest version of MeasureString?

A few days ago I settled on a workaround of just adding 4 to the width
returned by MeasureString, so the entire legend appears in both XP and
Vista. In XP it unnecessarily wastes a bit of the blank space after the
legend but it's still blank so the user won't notice the difference. I will
try your suggestions in Vista instead of adding that 4, and post again.
Meanwhile as mentioned, I still can't figure out why the simplest form of
MeasureString fell short.


"Ron" <rallen (AT) nospam (DOT) src-us.com> wrote

Quote:
Norman,
The measurements of the string depend on the StringFormat being used.
The default one includes a fair amount of space around the whole string
when measuring. For what you want to do one of the MeasureString calls
including a StringFormat would probably work best and include a clone of
StringFormat.GenericTypographic to get the closest meaurements around the
object being measured.
i.e. the following after you compute the starting point
legendSize = m_grChartResults.MeasureString(legend, this.Font,
new PointF(0, 0), StringFormat.GenericTypographic);
for a string at the top/left of the page. The starting location is used
because if there is some kind of non-linear transform done on the graphics
being used the size of the string depends on the location.

Ron Allen


"Norman Diamond" <ndiamond (AT) community (DOT) nospam> wrote in message
news:%23KwI8mFQIHA.1164 (AT) TK2MSFTNGP02 (DOT) phx.gbl...
In Windows XP, the following code figures out where to position a string
and draws the string. In Vista, the following code figures out where to
position all except the last character of the string and draws all except
the last character of the string.

Notice that this legend is located near the lower left of the chart and
there's lots of blank space on the right. (In fact after all that blank
space there's another legend at the lower right which suffers from
exactly the same defect, but I'm omitting that code because the
positioning might lead to a red herring. Anyway there's lots and lots of
blank space where there should be the last character and lots and lots of
blank space.)

legendSize = m_grChartResults.MeasureString(legend, this.Font);
legendRectangle.X = ChartLeftMargin - (legendSize.Width / 2.0f);
if (legendRectangle.X < 0)
{
legendRectangle.X = 0;
}
legendRectangle.Width = legendSize.Width;
legendRectangle.Y = pbChartResults.Height - legendSize.Height - 2;
legendRectangle.Height = legendSize.Height;
m_grChartResults.DrawString(legend, legendFont, legendBrush,
legendRectangle);


DotNet Framework 2 with SP1, Visual Studio 2005 with SP1 C#.



Reply With Quote
  #6  
Old   
Norman Diamond
 
Posts: n/a

Default Re: Graphics.MeasureString? or Graphics.DrawString? - 12-20-2007 , 08:05 PM



Bad news.

With your suggested changes to the MeasureString call, in Vista it now loses
the last 2 characters of each legend. The simplest version of Measure
String only lost the last 1 character of each legend, in Vista.

Rebooting to XP on the same machine, with your suggested changes to the
MeasureString call, it again loses the last 2 characters of each legend.
The simplest version of MeasureString didn't lose any characters at all from
the legends in XP.


"Ron" <rallen (AT) nospam (DOT) src-us.com> wrote

Quote:
Norman,
The measurements of the string depend on the StringFormat being used.
The default one includes a fair amount of space around the whole string
when measuring. For what you want to do one of the MeasureString calls
including a StringFormat would probably work best and include a clone of
StringFormat.GenericTypographic to get the closest meaurements around the
object being measured.
i.e. the following after you compute the starting point
legendSize = m_grChartResults.MeasureString(legend, this.Font,
new PointF(0, 0), StringFormat.GenericTypographic);
for a string at the top/left of the page. The starting location is used
because if there is some kind of non-linear transform done on the graphics
being used the size of the string depends on the location.

Ron Allen


"Norman Diamond" <ndiamond (AT) community (DOT) nospam> wrote in message
news:%23KwI8mFQIHA.1164 (AT) TK2MSFTNGP02 (DOT) phx.gbl...
In Windows XP, the following code figures out where to position a string
and draws the string. In Vista, the following code figures out where to
position all except the last character of the string and draws all except
the last character of the string.

Notice that this legend is located near the lower left of the chart and
there's lots of blank space on the right. (In fact after all that blank
space there's another legend at the lower right which suffers from
exactly the same defect, but I'm omitting that code because the
positioning might lead to a red herring. Anyway there's lots and lots of
blank space where there should be the last character and lots and lots of
blank space.)

legendSize = m_grChartResults.MeasureString(legend, this.Font);
legendRectangle.X = ChartLeftMargin - (legendSize.Width / 2.0f);
if (legendRectangle.X < 0)
{
legendRectangle.X = 0;
}
legendRectangle.Width = legendSize.Width;
legendRectangle.Y = pbChartResults.Height - legendSize.Height - 2;
legendRectangle.Height = legendSize.Height;
m_grChartResults.DrawString(legend, legendFont, legendBrush,
legendRectangle);


DotNet Framework 2 with SP1, Visual Studio 2005 with SP1 C#.



Reply With Quote
  #7  
Old   
Ron
 
Posts: n/a

Default Re: Graphics.MeasureString? or Graphics.DrawString? - 12-31-2007 , 11:16 AM



Norman,
I don't know why this would happen but I use the
StringFormat.GenericTypographic all through my utilities library for
printing and it works just fine for centering, left aligning, etc. I only
mentioned the Transform because that is why you need a position to measure
from. I do note that you are measuring with this.Font and then drawing with
legendFont though which may produce differnent results if the two Font
objects are different.

Ron Allen
"Norman Diamond" <ndiamond (AT) community (DOT) nospam> wrote

Quote:
Bad news.

With your suggested changes to the MeasureString call, in Vista it now
loses the last 2 characters of each legend. The simplest version of
Measure String only lost the last 1 character of each legend, in Vista.

Rebooting to XP on the same machine, with your suggested changes to the
MeasureString call, it again loses the last 2 characters of each legend.
The simplest version of MeasureString didn't lose any characters at all
from the legends in XP.


"Ron" <rallen (AT) nospam (DOT) src-us.com> wrote in message
news:A3CC59CC-B04F-4D43-8299-F668AB568052 (AT) microsoft (DOT) com...
Norman,
The measurements of the string depend on the StringFormat being used.
The default one includes a fair amount of space around the whole string
when measuring. For what you want to do one of the MeasureString calls
including a StringFormat would probably work best and include a clone of
StringFormat.GenericTypographic to get the closest meaurements around the
object being measured.
i.e. the following after you compute the starting point
legendSize = m_grChartResults.MeasureString(legend, this.Font,
new PointF(0, 0), StringFormat.GenericTypographic);
for a string at the top/left of the page. The starting location is used
because if there is some kind of non-linear transform done on the
graphics being used the size of the string depends on the location.

Ron Allen


"Norman Diamond" <ndiamond (AT) community (DOT) nospam> wrote in message
news:%23KwI8mFQIHA.1164 (AT) TK2MSFTNGP02 (DOT) phx.gbl...
In Windows XP, the following code figures out where to position a string
and draws the string. In Vista, the following code figures out where to
position all except the last character of the string and draws all
except the last character of the string.

Notice that this legend is located near the lower left of the chart and
there's lots of blank space on the right. (In fact after all that blank
space there's another legend at the lower right which suffers from
exactly the same defect, but I'm omitting that code because the
positioning might lead to a red herring. Anyway there's lots and lots
of blank space where there should be the last character and lots and
lots of blank space.)

legendSize = m_grChartResults.MeasureString(legend, this.Font);
legendRectangle.X = ChartLeftMargin - (legendSize.Width / 2.0f);
if (legendRectangle.X < 0)
{
legendRectangle.X = 0;
}
legendRectangle.Width = legendSize.Width;
legendRectangle.Y = pbChartResults.Height - legendSize.Height - 2;
legendRectangle.Height = legendSize.Height;
m_grChartResults.DrawString(legend, legendFont, legendBrush,
legendRectangle);


DotNet Framework 2 with SP1, Visual Studio 2005 with SP1 C#.




Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.