System.Drawing: Texts are not top-aligned with DrawString - c#

In windows application(C#), When draw string using DrawString function of System.Drawing.Graphics class. But values are not properly aligned with other values though X and Y coordinates are the same. It behaves differently for different fonts with different font sizes. I have considered an internal leading and deduct it from Y coordinate but still is not working for all font types.
In my example, I want all text part to be top-aligned with the horizontal line. But for different fonts and font size, It is not aligned properly. It is working for first font(Avenir Black) but not for others.
Below is the code I am using to generate this printed document:
static void PrintDocument(string filePath)
{
// Create new document
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(delegate (Object sender, PrintPageEventArgs e)
{
//e.Graphics.Clear(Color.White);
var Canvas = e.Graphics;
var rectF = new RectangleF(0f, 100, 1000, 78.74016f);
Pen p = new Pen(Color.Black);
p.Width = 1 / 2;
p.DashStyle = DashStyle.Solid;
Canvas.DrawLine(p, rectF.X, rectF.Y, rectF.X + rectF.Width, rectF.Y);
rectF = new RectangleF(0f, 100, 250, 78.74016f);
DrawPrice(Canvas, "Avenir Black", ref rectF);
rectF.X += 20;
rectF.Y = 100;
DrawPrice(Canvas, "Arial", ref rectF);
rectF.X += 20;
rectF.Y = 100;
DrawPrice(Canvas, "Calibri", ref rectF);
rectF.X += 20;
rectF.Y = 100;
DrawPrice(Canvas, "Times New Roman", ref rectF);
});
pd.Print();
Process.Start(filePath);
}
private static void DrawPrice(Graphics Canvas, string fontName, ref RectangleF rectF)
{
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
var superFont = new Font(fontName, 20, new FontStyle());
var font = new Font(fontName, 61, new FontStyle());
Brush brush = new SolidBrush(Color.FromName("black"));
var currencySymbol = "$";
var mainPrice = "29";
var cents = "50";
var superFontMetrics = FontInfo(Canvas, superFont, GraphicsUnit.Point);
var fontMetrics = FontInfo(Canvas, font, GraphicsUnit.Point);
var symbolSize = Canvas.MeasureString(currencySymbol, superFont, rectF.Size, format);
var centsSize = Canvas.MeasureString(cents, superFont, rectF.Size, format);
var dollarSize = Canvas.MeasureString(mainPrice, font, rectF.Size, format);
Canvas.DrawString(currencySymbol, superFont, brush, new RectangleF(rectF.X, rectF.Y - superFontMetrics.InternalLeading, symbolSize.Width, symbolSize.Height), format);
rectF.X += symbolSize.Width;
Canvas.DrawString(mainPrice, font, brush, new RectangleF(rectF.X, rectF.Y, dollarSize.Width, rectF.Height), format);
var mainPriceX = rectF.X + (dollarSize.Width / 2);
rectF.X += dollarSize.Width;
Canvas.DrawString(cents, superFont, brush, new RectangleF(rectF.X, rectF.Y - superFontMetrics.InternalLeading, centsSize.Width, centsSize.Height), format);
rectF.Y += rectF.Height;
rectF.X += centsSize.Width;
var titleFont = new Font(fontName, 5, new FontStyle());
var titleTextSize = Canvas.MeasureString(fontName, titleFont, rectF.Size, format);
Canvas.DrawString(fontName, titleFont, brush, new RectangleF(mainPriceX, rectF.Y, titleTextSize.Width, titleTextSize.Height), format);
}
public static FontMetrics FontInfo(Graphics gr, Font font, GraphicsUnit toUnit)
{
FontMetrics metrics = new FontMetrics();
float em_height = font.FontFamily.GetEmHeight(font.Style);
metrics.EmHeight = ConvertUnits(gr, font.Size, font.Unit, toUnit);
float design_to_points = metrics.EmHeight / em_height;
metrics.Ascent = design_to_points * font.FontFamily.GetCellAscent(font.Style);
metrics.Descent = design_to_points * font.FontFamily.GetCellDescent(font.Style);
metrics.CellHeight = metrics.Ascent + metrics.Descent;
metrics.InternalLeading = metrics.CellHeight - metrics.EmHeight;
metrics.LineSpacing = design_to_points * font.FontFamily.GetLineSpacing(font.Style);
metrics.ExternalLeading = metrics.LineSpacing - metrics.CellHeight;
return metrics;
}

After using GraphicsPath >> AddString method to print string, I got the result I want i.e. printed texts are top aligned for all type of fonts. Here is the output:
Below is the code I used:
private void DrawStringByGraphicsPath(Graphics g, Font font, Brush brush, ref RectangleF rectF, RectangleF elementRectF, StringFormat format, string text)
{
if (!string.IsNullOrEmpty(text))
{
using (GraphicsPath graphicsPath = new GraphicsPath())
{
graphicsPath.AddString(text, font.FontFamily, (int)font.Style, GetEMSize(g, font), elementRectF.Location, format);
// this is the net bounds without any whitespace:
RectangleF br = graphicsPath.GetBounds();
// Transform it for top alignment
g.TranslateTransform(elementRectF.X - br.X, (elementRectF.Y - br.Y));
g.FillPath(brush, graphicsPath);
g.ResetTransform();
}
}
}
private float GetEMSize(Graphics canvas, Font font)
{
return (font.SizeInPoints * (font.FontFamily.GetCellAscent(font.Style) + font.FontFamily.GetCellDescent(font.Style))) / font.FontFamily.GetEmHeight(font.Style);
}

Related

Barcode not detected through barcode scanner after printing

I 'm using the code below to print the barcode that gets generated in my C# WinForms, but the barcode scanner does not detect it, I've tried using code 128 font and code39 fonts with no luck, when I print using the bartender software it detects the barcode generated, just won't detect mine
here is the code
private void txtPprice_TextChanged(object sender, EventArgs e)
{
string barcode = txtCode.Text;
string price = txtPprice.Text;
string pname = txtPname.Text;
Bitmap bitm = new Bitmap(barcode.Length * 30, 90);
using (Graphics graphic = Graphics.FromImage(bitm))
{
Font newfont = new Font("IDAutomationHC39M", 10);
Font newfont2 = new Font("Arial Black", 8);
PointF point = new PointF(10f, 10f);
SolidBrush black = new SolidBrush(Color.Black);
SolidBrush white = new SolidBrush(Color.White);
graphic.FillRectangle(white, 0, 0, bitm.Width, bitm.Height);
graphic.DrawString("*" + barcode + "*", newfont, black, point);
PointF pointPrice = new PointF(45f, 55f);
graphic.DrawString("" + pname +"", newfont2, black, pointPrice);
PointF pointPname = new PointF(90f, 75f);
graphic.DrawString("" + price + " L.E.", newfont2, black, pointPname);
PointF pointBcode = new PointF(20f, 75f);
graphic.DrawString("" + barcode + "", newfont2, black, pointBcode);
}
using (MemoryStream Mmst = new MemoryStream())
{
bitm.Save("ms", ImageFormat.Jpeg);
pictureBox1.Image = bitm;
pictureBox1.Width = bitm.Width;
pictureBox1.Height = bitm.Height;
}
}
I have tried adding and removing the * as suggested in other posts, also changing the font size from 8p went one by one till 28px, but still no luck
the scanner and the printer are working fine on the bartender application
The code used in the example below is 5094411
Here is an image, the textbox highlighted in red is where the string barcode is coming from
and you can see in the image that in the picturebox it shows 5094411 in both IDautomationHC39M font (the barcode font) and again below it in Arial
This is the correct code that after some tries with the help of Jimi here I was able to get this part right
string Barcode = "*"+txtCode.Text+"*";
string price = txtPprice.Text;
string pname = txtPname.Text;
using (Bitmap bitmap = new Bitmap(350, 220))
{
bitmap.SetResolution(240, 240);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
Font font = new Font("IDAutomationHC39M", 10, FontStyle.Regular, GraphicsUnit.Point);
graphics.Clear(Color.White);
StringFormat stringformat = new StringFormat(StringFormatFlags.NoWrap);
graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
graphics.TextContrast = 10;
SolidBrush black = new SolidBrush(Color.Black);
SolidBrush white = new SolidBrush(Color.White);
PointF TextPosition = new PointF(45F, 10F);
SizeF TextSize = graphics.MeasureString(Barcode, font, TextPosition, stringformat);
PointF pointPrice = new PointF(90f, 125f);
Font newfont2 = new Font("Cambria", 8, FontStyle.Regular, GraphicsUnit.Point);
Font newfont3 = new Font("Arial Black", 10, FontStyle.Regular, GraphicsUnit.Point);
graphics.DrawString("" + pname + "", newfont3, black, pointPrice);
PointF pointPname = new PointF(200f, 170f);
graphics.DrawString("" + price + " L.E.", newfont3, black, pointPname);
PointF pointBcode = new PointF(35f, 170f);
graphics.DrawString("" + Barcode + "", newfont2, black, pointBcode);
if (TextSize.Width > bitmap.Width)
{
float ScaleFactor = (bitmap.Width - (TextPosition.X / 2)) / TextSize.Width;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.ScaleTransform(ScaleFactor, ScaleFactor);
}
graphics.DrawString(Barcode, font, new SolidBrush(Color.Black), TextPosition, StringFormat.GenericTypographic);
bitmap.Save(#"barcode.png", ImageFormat.Png);
this.pictureBox1.Image = (Bitmap)bitmap.Clone();
font.Dispose();
}
}

Graphics.DrawString to multiple rectangles

I am trying to write a function that needs to draw a string to an image. The image has anywhere from 1-5 textboxes, which each have a x,y, width, and height. These details are defined in an XML file which I am parsing, so I have access to these for each box.
My question is whether or not I can use the graphics.DrawString (or a similar) method to do this easily. The sample function below will create a rectangle with specified x,y, width, height, and then draw a string within. If the string doesn't fit, it truncates.
public void DrawStringRectangleFormat(Graphics g)
{
// Create string to draw.
String drawString = "Sample Text is too long to fit into this tiny lil rectangle area right here";
// Create font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create rectangle for drawing.
float x = 150.0F;
float y = 150.0F;
float width = 200.0F;
float height = 50.0F;
RectangleF drawRect = new RectangleF(x, y, width, height);
// Set format of string.
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
// Draw string to screen.
g.DrawString(drawString, drawFont, drawBrush, drawRect, drawFormat);
}
What I want instead of this, is rather than truncating, it will stop at the last fitting word, and go to the next rectangle(textbox). This way I can use all the available textboxes.
Is there a method already made to do this? Otherwise I will need to implement my own drawString method.
OK, what you would have to do is loop through each char in the string, and concatenate to a final string..
so basically foreach (char c in mystring)...
then using measurestring, you check to see if the string is over the box length, if it is, start on the next rect...
https://msdn.microsoft.com/en-us/library/6xe5hazb(v=vs.110).aspx
This solution uses the StringFormat's settings to ensure that each call to DrawString only draws the words that fit. Then, Graphics.MeasureCharacterRanges calculates the words that don't fit into the rectangle, and the remaining text overflows into the next layout rectangle.
You might need to customize how the input string is split into words. Right now I'm just splitting it apart at whitespace boundaries.
using System.Text.RegularExpressions;
using System.Drawing;
/// <summary>
/// Draw a string using one or more layout rectangles. Words which don't fit will overflow into the next layout rectangle.
/// </summary>
private static void DrawOverflowString(Graphics graphics, string drawString, RectangleF[] layoutRectangles, StringAlignment alignment)
{
var drawFont = new Font("Arial", 16.0f);
var black = new SolidBrush(Color.Black);
var format = new StringFormat()
{
Alignment = alignment,
Trimming = StringTrimming.Word,
FormatFlags = StringFormatFlags.LineLimit
};
var wordRegex = new Regex("[^\\s]+");
string remainingText = drawString;
foreach (var layoutRect in layoutRectangles)
{
// Draw everything that will fit into this text box
graphics.DrawString(remainingText, drawFont, black, layoutRect, format);
// calculate which words did not fit
var wordMatches = wordRegex.Matches(remainingText);
var ranges = wordMatches.OfType<Match>().Select(x => new CharacterRange(x.Index, x.Length)).ToArray();
format.SetMeasurableCharacterRanges(ranges);
var wordRegions = graphics.MeasureCharacterRanges(remainingText, drawFont, layoutRect, format);
var allfit = true;
for (int i = 0; i < wordRegions.Length; i++)
{
if (wordRegions[i].GetBounds(graphics).Width == 0.0f)
{
allfit = false;
remainingText = remainingText.Substring(wordMatches[i].Index);
break;
}
}
if (allfit)
break;
}
drawFont.Dispose();
black.Dispose();
}
protected override void OnPaint(PaintEventArgs e)
{
// Call the OnPaint method of the base class.
base.OnPaint(e);
List<Rectanglestring> testrecs = new List<Rectanglestring>();
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 12, 40, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring {targetrect= new Rectangle(0, 25, 35, 12),whattodraw="" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 35, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 45, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 65, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 85, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 95, 55, 12), whattodraw = "" });
string mystringtofit = "This is just an example";
foreach (Rectanglestring rect in testrecs)
{
for (int i = 0; i < mystringtofit.Length; i++)
{
if (mystringtofit[i] == ' ' && rect.whattodraw.Length > 0) break;
if (mystringtofit[i] == ' ') continue;
string teststring = rect.whattodraw + mystringtofit[i];
SizeF stringSize = stringSize = e.Graphics.MeasureString(teststring, new Font("Ariel", 12));
if (stringSize.Width >= rect.targetrect.Width) break;
rect.whattodraw += mystringtofit[i];
}
mystringtofit = mystringtofit.Substring(rect.whattodraw.Length);
if (mystringtofit.StartsWith(" "))
{
mystringtofit = mystringtofit.Substring(1);
}
e.Graphics.DrawString(rect.whattodraw, Font, new SolidBrush(ForeColor), rect.targetrect);
}
// Call methods of the System.Drawing.Graphics object.
}
public class Rectanglestring
{
public Rectangle targetrect = new Rectangle();
public string whattodraw = "";
}
This is what I have. It does what I described. Thanks for the answers.
public void DrawStringInTextboxes(string text, Graphics g)
{
String drawString = text;
PrivateFontCollection fontCollection = new PrivateFontCollection();
fontCollection.AddFontFile(System.Web.Hosting.HostingEnvironment.MapPath("~/Content/Fonts/Squidgingtons.ttf"));
var squidingtonsFontFamily = fontCollection.Families[0];
Font squidingtons = new Font(squidingtonsFontFamily, textParameters[0].MaxFontSize);
Font drawFont = new Font("Arial", 60);
SolidBrush drawBrush = new SolidBrush(Color.Black);
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
char[] delimiterChars = { ' ' };
string[] words = drawString.Split(delimiterChars);
string finalString = "";
int textBoxIndex = 0;
foreach (string word in words)
{
//set the dimensions for the first textbox and create a rectangle with those specifications.
float x = textParameters[textBoxIndex].Left;
float y = textParameters[textBoxIndex].Top;
float width = textParameters[textBoxIndex].Width;
float height = textParameters[textBoxIndex].Height;
RectangleF Rect = new RectangleF(x, y, width, height);
//if the current finalString + the next word fits in the current box, add the word to finalString.
if (g.MeasureString(finalString + word + " ", squidingtons).Width < textParameters[textBoxIndex].Width)
{
finalString = finalString + " " + word;
//if this is the last word, print the finalString and we are done.
if (word == words[words.Length - 1])
{
g.DrawString(finalString, squidingtons, drawBrush, Rect, drawFormat);
break;
}
}
//the current finalString + next word did not fit in the box. Draw what we have to the first box.
else {
g.DrawString(finalString, squidingtons, drawBrush, Rect, drawFormat);
//Hold onto the word that didnt fit. It will be the first word of the next box.
finalString = word;
if (textBoxIndex +1 >= textParameters.Length)
{
//if we are out of textboxes, we are done.
break;
}
else
{
//move on to the next textbox. The loop begins again with new specifications set for the textbox.
textBoxIndex++;
}
}
}
squidingtons.Dispose();
drawBrush.Dispose();
drawFont.Dispose();
}

How to vertical text alignment for formattedtext?

is it possible to setting vertical text alignment to formatted text in c#
for example
my formatted text is
var formattedtext=new FormattedText("some string", CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, this.GetTypeface(), 12.0, Brushes.Black);
i need align the formatted text in vertical alignment center with in the particular rect region.
Here is how you could achieve that.
My approach will also scale down to fit inside the bounding box in case text overflows limits.
/// <summary>
/// Use to draw some text using font file location.
/// </summary>
/// <param name="font">Font file location</param>
/// <param name="someText"></param>
/// <param name="fontSize"></param>
/// <param name="width">bitmap width</param>
/// <param name="height">bitmap height</param>
/// <returns>new instance of RenderTargetBitmap</returns>
private static RenderTargetBitmap DrawText(string font, string someText, int fontSize, int width = 700, int height = 300)
{
var name = Path.GetFileName(font);
var glyphTypeface = new GlyphTypeface(new Uri(font));
string family = String.Join(" ", glyphTypeface.FamilyNames.Values.ToArray<string>());
var style = glyphTypeface.Style;
var weight = glyphTypeface.Weight;
var fontStretch = glyphTypeface.Stretch;
string fontUri = new Uri(font.Replace(name, ""), UriKind.RelativeOrAbsolute).AbsoluteUri + "/#" + family;
var fontFamily = new FontFamily(fontUri);
var typeface = new Typeface(fontFamily, style, weight, fontStretch);
var formattedText = new FormattedText(someText, System.Globalization.CultureInfo.InvariantCulture,
FlowDirection.LeftToRight,
typeface, fontSize,
Brushes.Black);
formattedText.TextAlignment = TextAlignment.Center;
var drawingVisual = new DrawingVisual();
RenderOptions.SetBitmapScalingMode(drawingVisual, BitmapScalingMode.HighQuality);
RenderOptions.SetEdgeMode(drawingVisual, EdgeMode.Aliased);
TextOptions.SetTextRenderingMode(drawingVisual, TextRenderingMode.Aliased);
using (var drawingContext = drawingVisual.RenderOpen())
{
drawingContext.DrawRectangle(Brushes.White, null, new Rect(0, 0, width, height));
var geometry = formattedText.BuildGeometry(new Point(0, 0));
var bounds = geometry.Bounds;
var sW = width / bounds.Width;
var sH = height / bounds.Height;
var ratio = sH <= sW ? sH : sW;
if (ratio > 1) ratio = 1;
var translateX = (width - bounds.Width * ratio) / 2;
var translateY = (height - bounds.Height * ratio) / 2;
var transformGroup = new TransformGroup();
transformGroup.Children.Add(new ScaleTransform(ratio, ratio));
transformGroup.Children.Add(new TranslateTransform(-bounds.X * ratio + translateX, -bounds.Y * ratio + translateY));
geometry.Transform = transformGroup;
drawingContext.DrawGeometry(Brushes.Black, null, geometry);
}
var renderTargetBitmap = new RenderTargetBitmap(
width, height,
0, 0,
PixelFormats.Pbgra32);
renderTargetBitmap.Render(drawingVisual);
return renderTargetBitmap;
}
Usage:
//Setting System.Windows.Control.Image source
image.Source = DrawText(#"C:\Windows\Fonts\ariali.ttf", "Lorem ipsum dolor sit amet,\nconsectetur adipisicing elit,\nsed do eiusmod tempor", 50);
You can try something like this:
// e is the PaintEventArgs, which is passed as a parameter
// construct a new Rectangle .
Rectangle displayRectangle =
new Rectangle (new Point(40, 40), new Size (80, 80));
// construct new StringFormat object
var format = new StringFormat(StringFormatFlags.DirectionVertical);
// set the LineAlignment and Alignment properties for
format.LineAlignment = StringAlignment.Near;
format.Alignment = StringAlignment.Center;
// draw the bounding rectangle and a string for the StringFormat object.
e.Graphics.DrawRectangle(Pens.Black, displayRectangle);
e.Graphics.DrawString("Showing Format", this.Font,
Brushes.Red, (RectangleF)displayRectangle, format);

Why isn't this code able to centre the text on the graphics object?

I've been hit and miss with using the graphics object method MeasureCharacterRanges(). Below is example code where it doesn't work. When the rectangle is drawn, it's not around the 'X', but slightly to the left.
'X', clearly, does not mark the spot.
Why?
public partial class Form1 : Form
{
private string test = "X";
public Form1()
{
InitializeComponent();
this.ResizeRedraw = true;
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
using (Graphics g = this.CreateGraphics())
{
g.Clear(this.BackColor);
using (Font font = new Font(Font.Name, this.Size.Height / 8))
{
Rectangle layout = this.ClientRectangle;
layout.Width *= 2;
using (StringFormat stringFormat = new StringFormat())
{
CharacterRange[] charRange = { new CharacterRange(0, test.Length) };
stringFormat.SetMeasurableCharacterRanges(charRange);
Region[] sr = g.MeasureCharacterRanges(test, font, layout, stringFormat);
RectangleF rectangle = sr[0].GetBounds(g);
PointF location = new PointF((this.ClientRectangle.Width - rectangle.Width) / 2.0f, ((this.ClientRectangle.Height - rectangle.Height) / 2.0F));
rectangle.Location = location;
using (SolidBrush brush = new SolidBrush(Color.Black))
{
g.DrawString(test, font, brush, rectangle.Location);
}
g.DrawRectangle(Pens.Red, Rectangle.Round(rectangle));
}
}
}
}
}
You need to create your StringFormat with the GenericTypographic property, and then pass the stringFormat into the DrawString method with one of the other overloads so that it knows about the StringFormat you've specified.
If you don't do this, DrawString just uses the default StringFormat which doesn't have the correct Property values for Trimming, FormatFlags and Alignment etc.
// StringFormat created using GenericTypographic
using (StringFormat stringFormat = new StringFormat(StringFormat.GenericTypographic))
{
CharacterRange[] charRange = { new CharacterRange(0, test.Length) };
stringFormat.SetMeasurableCharacterRanges(charRange);
Region[] sr = g.MeasureCharacterRanges(test, font, layout, stringFormat);
RectangleF rectangle = sr[0].GetBounds(g);
PointF location = new PointF((this.ClientRectangle.Width - rectangle.Width) / 2.0f, ((this.ClientRectangle.Height - rectangle.Height) / 2.0F));
rectangle.Location = location;
using (SolidBrush brush = new SolidBrush(Color.Black))
{
// Now passing in stringFormat
g.DrawString(test, font, brush, rectangle.Location, stringFormat);
}
g.DrawRectangle(Pens.Red, Rectangle.Round(rectangle));
}

how can i change font size in thermal printing (lipi lwt 150) using C#.net

I am using C#.net and GDI printing code to print to thermal printer LIPI LWT 150. But, I can't change my font size. I'm using Arial 9pt and 5pt, but it comes out in default size.
Does anybody have any idea about this?
I am using C# code like this:
public frmSale()
{
InitializeComponent();
printingDoc.PrintPage += new PrintPageEventHandler(Form_PrintPage);
}
//initalizing print document
private void PrintSettings()
{
printingDoc.DefaultPageSettings.Margins = new Margins(3, 3, 3, 3);
PaperSize pSize = new PaperSize();
pSize.Width = 275;
printingDoc.DefaultPageSettings.PaperSize = pSize;
// Claculating the PageWidth and the PageHeight
PageHeight = printingDoc.DefaultPageSettings.PaperSize.Height;
PageWidth = printingDoc.DefaultPageSettings.PaperSize.Width;
// Claculating the page margins
LeftMargin = printingDoc.DefaultPageSettings.Margins.Left;
TopMargin = printingDoc.DefaultPageSettings.Margins.Top;
RightMargin = printingDoc.DefaultPageSettings.Margins.Right;
BottomMargin = printingDoc.DefaultPageSettings.Margins.Bottom;
printAreaWidth = PageWidth - RightMargin - LeftMargin;
}
private void Form_PrintPage(object o, PrintPageEventArgs e)
//Here we Begin All the printing Process...
{
PrintSettings();
CurrentY = (float)printingDoc.DefaultPageSettings.Margins.Top;//0;
PrintEstHeader(e.Graphics);
DrawEstGridData(e);
}
//Printing Function
private void PrintEstData(Graphics g, string stringData, StringAlignment alignment, Font fnt, Color clr, bool newLine)//,int starting,int maxWidth)
{
StringFormat stringFormat = new StringFormat();
stringFormat.Trimming = StringTrimming.Word;
stringFormat.FormatFlags = StringFormatFlags.NoWrap |
StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
stringFormat.Alignment = alignment;
RectangleF Rect = new RectangleF((float)LeftMargin, CurrentY,
(float)PageWidth - (float)RightMargin - (float)LeftMargin,
g.MeasureString(stringData, fnt).Height);
g.DrawString(stringData, fnt,
new SolidBrush(clr),
Rect, stringFormat);
CurrentY += newLine ? g.MeasureString(stringData, fnt).Height : 0;
}
private void PrintEstHeader(Graphics g)
{
PrintEstData(g, "----------------------------------------------", StringAlignment.Near, new Font("Arial", 9), Color.Black, true);//,LeftMargin,printAreaWidth);
PrintEstData(g, "Estimate" + " " + "Rate :" + ncRate.Value.ToString("0.00"), StringAlignment.Near, new Font("Arial", 9, FontStyle.Bold), Color.Black, true);//, LeftMargin, 76);
PrintEstData(g, "----------------------------------------------", StringAlignment.Near, new Font("Arial", 9), Color.Black, true);//, LeftMargin, printAreaWidth);
PrintEstData(g,"|ITEM |"+"WEIGHT|"+ "STN WT|"+"M.C. %|"+"Total|", StringAlignment.Near, new Font("Arial", 5), Color.Black, true);//,LeftMargin,42);
PrintEstData(g, "----------------------------------------------", StringAlignment.Near, new Font("Arial", 9), Color.Black, true);//, LeftMargin, printAreaWidth);
}
Based on the printer specification it looks like it does not support arbitrary fonts, but only two inbuilt fixed width fonts. Unless you can print bitmaps to the printer or create user characters I doubt if you will be able to do more than select Font A or Font B.

Categories

Resources