How to get contents in graphics.Drawstring in new line of c# - c#

Hello I am printing a text on Receipt printer
on which I have to print Product name But products name get overwrites on Qty field can i get that name string in new line after particular length I am using following Code.
column 3 have a Product name Like (Almond Kesar Kanti Body Cleanser) How to get this text in new line and manage space of Invoice.
while (i < dataGridView2.Rows.Count)
{
if (height > e.MarginBounds.Height)
{
height = 500;
width = 500;
//e.HasMorePages = true;
return;
}
//height += dataGridView1.Rows[i].Height;
// e.Graphics.DrawRectangle(Pens.Black, 20, height, dataGridView1.Columns[0].Width, dataGridView1.Rows[0].Height);
e.Graphics.DrawString(dataGridView2.Rows[i].Cells["Column3"].FormattedValue.ToString(), dataGridView2.Font, Brushes.Black, CurrentX, CurrentY + 20);
e.Graphics.DrawString(dataGridView2.Rows[i].Cells["Column4"].FormattedValue.ToString(), dataGridView2.Font, Brushes.Black, CurrentX + 150, CurrentY + 20);
// e.Graphics.DrawString(dataGridView2.Rows[i].Cells["Column5"].FormattedValue.ToString(), dataGridView2.Font, Brushes.Black, CurrentX + 150, CurrentY + 20);
e.Graphics.DrawString(dataGridView2.Rows[i].Cells["Column10"].FormattedValue.ToString(), dataGridView2.Font, Brushes.Black, CurrentX + 200, CurrentY + 20);
i++;
CurrentY = CurrentY + 20;
}

You are not actually incrementing your CurrentY variable between the calls to DrawString. Therefore each line is printed at the same Y-coordinate.
Add CurrentY = CurrentY + 20; between each call to DrawString and just use
e.Graphics.DrawString(dataGridView2.Rows[i].Cells["Column3"].FormattedValue.ToString(), dataGridView2.Font, Brushes.Black, CurrentX, CurrentY);
Better yet, don't increment it by a fixed value but use e.Graphics.MeasureString to calculate the actual height of each line and increment by this value+spacing, like in this example:
Bitmap bmp = new Bitmap(200, 200);
using (Graphics g = Graphics.FromImage(bmp)) {
//The individual lines to draw
string[] lines = {
"Foo1",
"Foo2",
"Foo3"
};
int y = 1; //The starting Y-coordinate
int spacing = 10; //The space between each line in pixels
for (i = 0; i <= lines.Count - 1; i++) {
g.DrawString(lines[i], this.Font, Brushes.Black, 1, y);
//Increment the coordinate after drawing each line
y += Convert.ToInt32(g.MeasureString(lines[i], this.Font).Height) + spacing;
}
}
PictureBox1.Image = bmp;
Results:
Edit
To fit text into a given area you need to use a different overload of DrawString. You need to draw the string with a given LayoutRectangle like this:
Bitmap bmp = new Bitmap(200, 200);
using (Graphics g = Graphics.FromImage(bmp)) {
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
string LongText = "This is a really long text that should be automatically wrapped to a certain rectangle.";
Rectangle DestinationRectangle = new Rectangle(10, 10, 100, 150);
g.DrawRectangle(Pens.Red, DestinationRectangle);
using (StringFormat sf = new StringFormat()) {
g.DrawString(LongText, new Font("Arial", 9), Brushes.Black, DestinationRectangle, sf);
}
}
PictureBox1.Image = bmp;
The DestinationRectangle defines where the text is printed and it is automatically wrapped. The problem is, that the line spacing is defined by the Font you use, as you can see in this example with different fonts:
If you can't find a font that works for you (or define your own) you would need to split the text into words and fit them yourself into the given rectangle by drawing them word for word, measuring each with the MeasureString function and break the line when you would go over the limit.
But beware, text layout is hard, very very hard, to get all the corner cases right.

Related

Is it posble create text on image with higher quality in .net

I need to create some kind of graph in .net desktop application.
I use .Net Framework 4.7.2 and System.Drawing library.
The scenario looked like this.
In the console application I create a bitmap with X and Y axes and some simple lines and some text on those lines, nothing complicated.
After creating the bitmap, I save it as .bmp file.
The problem is that the letters and numbers I create are bad and look furry, I tried with different fonts and different settings but the result was always the same.
The picture looks like this:
and under a magnifyer it looks like this:
This is my sample code:
// create new bitmap
Bitmap bitmap = new Bitmap(900, 700, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Graphics g = Graphics.FromImage(bitmap);
g.Clear(Color.LightGray);
// set attr
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.Bicubic;
// draw X and Y axes
Pen pen = new Pen(Color.Black, 1);
g.DrawLine(pen, new Point(100, 100), new Point(100,600));
g.DrawLine(pen, new Point(100, 600), new Point(800, 600));
SolidBrush brush = new SolidBrush(Color.Black);
Font font = new Font("Lucida Console", 14, FontStyle.Bold);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.Bicubic;
// grid numbeers on x axis
for (int i = 0; i < 8; i++)
{
g.DrawString(i.ToString(), font, brush, 100 * (i+1), 620);
}
// grid numbeers on y axis
for (int i = 0; i < 6; i++)
{
g.DrawString(i.ToString(), font, brush, 70, 600 - (100 * i));
}
// label 1
font = new Font("Lucida Console", 14, FontStyle.Bold);
g.DrawString("Line - X axis", font, brush, 100, 650);
// label 2
font = new Font("Lucida Console", 32, FontStyle.Bold);
g.DrawString("PORCO El.01", font, brush, 550, 150);
// label 3
font = new Font("Lucida Console", 24, FontStyle.Regular);
g.DrawString("PORCO El.01", font, brush, 550, 200);
// save as .bmp file
bitmap.Save(Path.Combine(picturePath, "sample.bmp"));
Is it possible to get better text quality? Is there maybe another 3rd party library that can achieve better results?
Thanks in advance!

How to align watermark in an image

I'm trying to add multiple watermarks to an image with some gap in between. I have been able to achieve this with two small caveats though.
What I want is:
Watermark should be vertically center aligned.
The program need to stop adding watermark when there is no sufficient width and/or height left in the image (so that there is no cutting of text).
My code is:
static void WatermarkedImage(string path, string fileName, string message, string destFileName)
{
using (Image image = Image.FromFile(path + fileName))
{
Graphics graphics = Graphics.FromImage(image);
Font font = new Font("Arial", 20, FontStyle.Bold);
SolidBrush brush = new SolidBrush(Color.FromArgb(150, 255, 0, 0));
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
int index = 0;
float offsetX = image.Width / 3;
float offsetY = image.Height / 3;
int increment = Convert.ToInt32(image.Height * 0.15);
while (offsetY * 1.25 < image.Height)
{
Matrix matrix = new Matrix();
matrix.Translate(offsetX, offsetY);
matrix.Rotate(-45.0f);
graphics.Transform = matrix;
graphics.DrawString(message, font, brush, 0, 50, format);
offsetX += increment;
offsetY += increment;
index++;
}
image.Save(path + destFileName);
}
}
This is what I'm getting with this:
Desired Output.
Any help is much appreciated.
Thank You!
Update-1
To check if all of the text is inside the image, use MeasureString to see how large the string will be. From this you can construct a rectangle, transform each corner of said rectangle using the matrix, and check if they are all inside the image.
Your desired output does not have any offset on the x-axis, so you shouldn't increment x offset at all.
offsetY += increment;
index++;
}
while (offsetY * 1.25 < image.Height);
image.Save(path + destFileName);

Calculating text width for DXF

I am using netDXF (https://netdxf.codeplex.com/) to generate a DXF file for use with AutoCAD. However, I have an issue with getting the width of MText correct. I want to be able to define a width that the text should fit into, and change the width factor of the text (squash it horizontally) so that it fits in the defined area. So if I have a 40mm width to fit the text into and the text is 80mm long, it needs to have a width factor of 0.5. The only problem is that I don't know how to accurately determine the width of the text. I have tried the following methods and was unsuccessful in getting the correct result:
Why is Graphics.MeasureString() returning a higher than expected number?
Measure a String without using a Graphics object?
http://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations
I have attached my code. I am basically printing a horizontal line using each of the 3 methods to calculate text width and comparing it to the actual text width. If I change the font, I get varying results. I have attached two images. One using the code with Calibri and one with Arial. I need the line to be on the edges of the text no matter what font I use.
Here is my code:
public void TestMethod1()
{
Application.SetCompatibleTextRenderingDefault(false);
//text width in mm
float textWidth = 40;
float textHeight = 200;
string labelText = "HELLO WORLD!";
TextStyle textStyle = new TextStyle("Calibri");
DxfDocument dxf = new DxfDocument();
Layer layer1 = new Layer("layer1");
layer1.Color = new AciColor(0, 0, 255);
layer1.Name = "Text";
MText text1 = new MText(new Vector2(0, 0), textHeight, 0, textStyle);
text1.Layer = layer1;
text1.AttachmentPoint = MTextAttachmentPoint.MiddleCenter;
//Will the text fit in the bounds of the rectangle? If not change width factor so it does.
Font f = new Font(textStyle.FontName, textHeight);
Size size = TextRenderer.MeasureText(labelText, f);
SizeF sizeF = graphicsMeasureString(labelText, f);
int width = MeasureDisplayStringWidth(labelText, f);
float widthFactor = Math.Min(1, textWidth / sizeF.Width);
MTextFormattingOptions mtextOptions = new MTextFormattingOptions(text1.Style);
//mtextOptions.WidthFactor = widthFactor;
text1.Write(labelText, mtextOptions);
//Red, g.MeasureString
Line line1 = new Line(new Vector2(0 - sizeF.Width / 2, 0), new Vector2(0 + sizeF.Width / 2, 0));
line1.Color = new AciColor(255, 0, 0);
//Green, TextRenderer
Line line2 = new Line(new Vector2(0 - size.Width / 2, 5), new Vector2(0 + size.Width / 2, 5));
line2.Color = new AciColor(0, 255, 0);
//Yellow, MeasureDisplayStringWidth
Line line3 = new Line(new Vector2(0 - width / 2, -5), new Vector2(0 + width / 2, -5));
line3.Color = new AciColor(255, 255, 0);
dxf.AddEntity(text1);
dxf.AddEntity(line1);
dxf.AddEntity(line2);
dxf.AddEntity(line3);
dxf.Save("Text Width Test.dxf");
}
public SizeF graphicsMeasureString(string text, Font f)
{
Bitmap fakeImage = new Bitmap(1, 1);
Graphics g = Graphics.FromImage(fakeImage);
SizeF sizeF = g.MeasureString(text, f, new PointF(100, 0), StringFormat.GenericTypographic);
return sizeF;
}
public int MeasureDisplayStringWidth(string text, Font f)
{
Size size = TextRenderer.MeasureText(text, f);
Bitmap fakeImage = new Bitmap(1, 1);
Graphics g = Graphics.FromImage(fakeImage);
System.Drawing.StringFormat format = new System.Drawing.StringFormat();
System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0, 1000, 1000);
System.Drawing.CharacterRange[] ranges = { new System.Drawing.CharacterRange(0, text.Length) };
System.Drawing.Region[] regions = new System.Drawing.Region[1];
format.SetMeasurableCharacterRanges(ranges);
regions = g.MeasureCharacterRanges(text, f, rect, format);
rect = regions[0].GetBounds(g);
return (int)(rect.Right + 1.0f);
}

c#- How can I past PointF in to DrawString?

c#- How can I past PointF in to DrawString?
I try to past PointF into DrawString but it is not provide me.This is the code but ti is not provide me how can I do?
string txt = "A long line we're trying to fit inside a rectangle with custom line spacing";
Font font = new Font("Microsoft Sans Serif", 10, FontStyle.Bold);
SizeF fit = new SizeF(200, font.Height);
StringFormat fmt = StringFormat.GenericTypographic;
PointF pointf = new PointF(55,21);
//Rectangle ss = new Rectangle(new PointF(155.0F, 225.0F),txt);
int spacing = (int)(1.5 * font.Height);
int line = 0;
for (int ix = 0; ix < txt.Length; ) {
int chars, lines;
e.Graphics.MeasureString(txt.Substring(ix), font, fit, fmt, out chars, out lines);
e.Graphics.DrawString(txt.Substring(ix, chars), font, Brushes.Black, pointf, spacing * line);
++line;
ix += chars;
}
Please show me by code!
I think what you want is:
e.Graphics.DrawString(txt.Substring(ix, chars), font, Brushes.Black, pointf);
++line;
ix += chars;
// Set up for the next line.
pointf.Y = pointf.Y + (lines*font.Height) + spacing;
Note that I removed the last parameter to the DrawString call, and added code to update pointf.Y.

How to DrawText in the right position?

I want to draw a text using Graphic.DrawText method in a specific position. Suppose for example I need to draw my text giving the following bounds:
X = 10;
Y = 10;
Width = 100;
Height = 100;
I would expect that the left-most point of my string will be at 10, but this is the result if I add also a vertical line at X = 10:
g.DrawLine(Pen, new Point(10, 10), new Point(10, 100));
g.DrawString("Hello", Font, Color, new Rectangle(10, 10, 100, 100), Format);
As you can see my text seems shifted, it is not in correspondence of the line, which is at X = 10.
Why? How can I fix this problem?

Categories

Resources