Reputation: 113
i have to measure a string to determine the exact with, so that i can create a label an set the following information on the report to be printed out correctly.
i sow alot of postings about measure a stirng with Graphics.MeasureString but when i use these i don't get the exact millimeters as in the printout.
here my code:
public double getStingWith_mm(string InputText, string Fontname, bool TypeBold, bool TypeItalic, double Fontsize)
{
try
{
if (grU == null)
{
//grU = CreateGraphics();
//grU = Graphics.FromImage(new Bitmap(1, 1));
System.Drawing.Printing.PrintDocument PD = new System.Drawing.Printing.PrintDocument();
grU = PD.PrinterSettings.CreateMeasurementGraphics();
}
FontStyle fStyle = FontStyle.Regular;
try
{
if (TypeBold)
fStyle = FontStyle.Bold;
if (TypeItalic)
fStyle = FontStyle.Italic;
}
catch (Exception ex)
{
logger4net.Error("some error during creating of the fonts.", ex);
}
try
{
currentFont = new System.Drawing.Font(
new FontFamily(Fontname),
(int)Math.Ceiling(Fontsize), //next higher size!
fStyle,
GraphicsUnit.Millimeter);
}
catch (Exception ex)
{
logger4net.Error("some error during creating of the fonts " + Fontname, ex);
try
{
currentFont = new System.Drawing.Font(
new FontFamily("Arial"),
(int)Math.Ceiling(Fontsize), //next higher size!
fStyle,
GraphicsUnit.Millimeter);
}
catch (Exception ex2)
{
logger4net.Error("some error during creating of the fonts: we fall back to Arial!!", ex);
}
}
// Change the page scale.
grU.PageUnit = GraphicsUnit.Millimeter;
grU.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
SizeF size = grU.MeasureString(InputText, currentFont); //string format (zusatzparameter) , 495)
//SizeF result2 = grU.MeasureString(InputText, currentFont, int.MaxValue, StringFormat.GenericTypographic);
SizeF result2 = grU.MeasureString(InputText, currentFont, new PointF(0, 0), new StringFormat(StringFormatFlags.MeasureTrailingSpaces));
SizeF result3 = grU.MeasureString(InputText, currentFont, int.MaxValue, StringFormat.GenericTypographic);
int resultInt = MeasureDisplayStringWidth(grU, InputText, currentFont);
//return Math.Ceiling(size.Width);
return Math.Ceiling(result2.Width);
}
catch (Exception ex)
{
logger4net.Error(ex);
return 0;
}
return 0;
}
static public int MeasureDisplayStringWidth(Graphics graphics, string text, System.Drawing.Font font)
{
System.Drawing.StringFormat format = new System.Drawing.StringFormat();
System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0, 1000, 1000);
CharacterRange ranges = new System.Drawing.CharacterRange(0, text.Length);
List<CharacterRange> RangesArray = new List<CharacterRange>();
RangesArray.Add(ranges);
System.Drawing.Region[] regions = new System.Drawing.Region[1];
format.SetMeasurableCharacterRanges(RangesArray.ToArray());
regions = graphics.MeasureCharacterRanges(text, font, rect, format);
rect = regions[0].GetBounds(graphics);
return (int)(rect.Right + 1.0f);
}
in the function getStingWith_mm i got more reults values to check if one of my aproach could reach the right value!
now if i start this function with the text "test", font Arial 12, bold. i got a return value between 21 to 25 mm. but on the printout it's about 10 mm i don't the my error. all the other examplex on stackoverflow work with MeasureString and it should work...
most of my code i got it from the following posts how to measure width of a string precisely? How to determine width of a string when printed?
thx for any suggestion!
Upvotes: 2
Views: 382
Reputation: 113
after long testing i found out that i can't measure the with with the two methods to get the exact printout with. wo here is my solution usin itextsharp 4.x
public double getStingWith_mm(string InputText, string Fontname, bool TypeBold, bool TypeItalic, double Fontsize)
{
try
{
string fontPathName = "";
// get parent of System folder to have Windows folder
DirectoryInfo dirWindowsFolder = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.System));
// Concatenate Fonts folder onto Windows folder.
string strFontsFolder = Path.Combine(dirWindowsFolder.FullName, "Fonts");
// check fontname
// if Bold then search font name + " Bold "
// if Italic then search font name + " Italic "
//only opentype fonts set the name to "-Italic" or "-Bold"
if ((TypeBold) && (TypeItalic))
{
fontPathName = fontsKey.GetValue(Fontname + " Bold Italic " + "(TrueType)", string.Empty) as string;
}
else if (TypeBold)
{
fontPathName = fontsKey.GetValue(Fontname + " Bold " + "(TrueType)", string.Empty) as string;
}
else if (TypeItalic)
{
fontPathName = fontsKey.GetValue(Fontname + " Italic " + "(TrueType)", string.Empty) as string;
}
//fallback to normal name if empty or normal font!
if (fontPathName == string.Empty)
{
fontPathName = fontsKey.GetValue(Fontname + " (TrueType)", string.Empty) as string;
}
// font for special characters!!!
string specialCharFontName = Path.Combine(strFontsFolder, fontPathName);
BaseFont specialCharBaseFont = BaseFont.CreateFont(specialCharFontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
// setzen der Headline Fonts!
iTextSharp.text.Font currentITFont = null;
try
{
currentITFont = new iTextSharp.text.Font(
specialCharBaseFont,
(float)Fontsize,
iTextSharp.text.Font.NORMAL //set here bold or italic din't change the font measuement, so i set it in the fontname to load!
);
}
catch (Exception ex)
{
logger4net.Error("Font konnte nicht geladen werden: " + Fontname);
}
float returnvalue7 = currentITFont.GetCalculatedBaseFont(true).GetWidthPoint(InputText, (float)Fontsize);
double result4 = Utilities.PointsToMillimeters(returnvalue7);
return Math.Ceiling(result4);
}
catch (Exception ex)
{
logger4net.Error(ex);
return 0;
}
}
Upvotes: 3