how to change spaces between lines in winforms label? - c#

I have a label with unknown text. the text contains \n. I want a bigger space between the \n lines. How can I set it?

You can create custom label component and override it's measuring and painting, here you can find a snippet of a paint method which implements line spacing.
Edit: adding a snippet here in case the link is dead:
string text = "Sri Lanka";
Graphics g = e.Graphics;
Font font = new Font("Arial", 10);
Brush brush = new SolidBrush(Color.Black);
float lineSpacing = 0.5f;
SizeF size = g.MeasureString("A", font);
float pos = 0.0f;
for ( int i = 0; i < text.Length; ++i )
{
string charToDraw = new string(textIdea, 1);
g.DrawString(charToDraw, font, brush, pos, 0.0f);
SizeF sizeChar = g.MeasureString(charToDraw, font);
pos += sizeChar.Width + size.Width * lineSpacing;
}

Related

Draw rectangle box for letters

My code. Output:
Bitmap bitmap = new Bitmap(600, 300, PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(bitmap);
GraphicsPath path = new GraphicsPath();
StringFormat format = new StringFormat();
Rectangle rect = new Rectangle(0, 0, 600, 300);
SolidBrush Brush = new SolidBrush(Color.White);
g.FillRectangle(Brush, rect);
g.SmoothingMode = SmoothingMode.AntiAlias;
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
path.AddString(textBox1.Text, FontFamily.GenericSansSerif, (int)FontStyle.Bold, 128, rect, format);
Brush = new SolidBrush(Color.Blue);
g.FillPath(Brush, path);
float x = path.GetBounds().X;
float y = path.GetBounds().Y;
float w = path.GetBounds().Width / textBox1.Text.Length;
float h = path.GetBounds().Height;
Pen redPen = new Pen(Color.Red, 2);
for (int i = 0; i < textBox1.Text.Length+1; i++)
{
rect = new Rectangle((int)x, (int)y, (int)w*i, (int)h);
g.DrawRectangle(redPen, rect);
}
pictureBox1.Image = bitmap;
I am getting the wrong result in the output because I cannot get the corners of the letters and am using the wrong way.
But i need get correct pixels of letter corners, draw rectangle and fill it.
Like this:
This line made me find one error in your code:
for (int i = 0; i < textBox1.Text.Length+1; i++)
It should be:
for (int i = 0; i < textBox1.Text.Length; i++)
But then indeed only 3 red boxes seem to appear.
The reason for that is the first rectangle (with your code) is very small, because the width is (int)w*i. That should be (int)w*(i+1).
Now back to the place where you are drawing rectangles.
If you take the text 'WWWW', you will see that your solution seems pretty OK.
But if you test with 'IIII', ten you should note that the left-most 'I' is left aligned in the red box, and the right-most 'I' is right aligned in the red box.
You are drawing 4 equal boxes round 4 letters with different with.
A solution could be to draw the letters with a monospaced font.
or, if you do not want a monospaced font, look at How to measure width of character precisely?

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.

Align text to center in System.Drawing.RectangleF

I am trying to create a captcha image. I am generating a random string and rotating the text with a random angle and trying to create a byte array. Below is my code snippet:
Image img = Image.FromFile(#"C:\Images\BackGround.jpg");
RectangleF myRect = new RectangleF(0, 0, width, height);
objGraphics.DrawImage(img, myRect);
Matrix myMatrix = new Matrix();
int i = 0;
StringFormat formatter = new StringFormat();
formatter.Alignment = StringAlignment.Center;
for (i = 0; i <= myString.Length - 1; i++)
{
myMatrix.Reset();
int charLenght = myString.Length;
float x = width / (charLenght + 1) * i;
float y = height / 30F;
myMatrix.RotateAt(oRandom.Next(-40, 40), new PointF(x, y));
objGraphics.Transform = myMatrix;
objGraphics.DrawString(myString.Substring(i, 1), MyFont, MyFontEmSizes, MyFontStyles,
MySolidBrush, x, Math.Max(width, height) / 50, formatter );
objGraphics.ResetTransform();
}
Every thing is working fine, except that, the first character in my final image on the web page is crossing my left border of the rectangle. How can I align my text to the center of the rectangle?
Thanks.

Categories

Resources