Is it possible to stretch font in WinForms - c#

Is to possible to stretch Font in WinForms? What I am trying to accomplish is to stretch font to maximum available RichTextBox width. It should be something like viewbox in WPF.
My goal is to stretch font NOT TO resize it. All fonts I am using are mono spaced fonts.

yes it's possible to do this
private void button1_Click(object sender, EventArgs e)
{
Graphics gr = richTextBox1.CreateGraphics();
Brush brush = new SolidBrush(Color.Red);
float x = 0.0F;
float y = 0.0F;
float width = 200.0F;
float height = 50.0F;
Font drawFont = new Font("Arial", 18);
RectangleF drawRect = new RectangleF(x, y, width, height);
//here you can shrink as you want
gr.ScaleTransform(3, 1);
gr.DrawString("your text", drawFont, brush, drawRect);
}
Hope this help

Related

How to connect .DrawEllipse with .DrawString

I'm trying to write text inside circle (not centered by rectangle) alignment must be from line to line inside circle.
I have successfully drawn the circle and text. I did research on Stack Overflow and Google without success about putting text inside this circle.
private void Button1_Click(object sender, EventArgs e)
{
System.Drawing.Graphics graphicsObj;
graphicsObj = this.CreateGraphics();
// Create font and brush.
Font drawFont = new Font("Arial", 5);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create point for upper-left corner of drawing.
float x = 150.0F;
float y = 50.0F;
// Set format of string.
StringFormat drawFormat = new StringFormat();
drawFormat.FormatFlags = StringFormatFlags.FitBlackBox;
graphicsObj.DrawEllipse(Pens.Red, 20, 20, 350, 350);
graphicsObj.DrawString(richTextBox1.Text.ToString(), drawFont, drawBrush, x, y, drawFormat);
}
Looking for advise, not for exact code..
-> How to establish connection for text alignment based on rectangle.
Expected output like in this image : https://imge.to/i/miFif
exactly same but I need in C# Win.Form -> Wrap text inside a circular div
DrawString has an overload with format options:
...
DrawString(e.Cache, text, rect,
new StringFormat() {
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Center
});

Finding the bounding rectangle of text with alignment

I'm trying to draw a box around a label which has been aligned using StringAlignment.Far for example. I can find the Size of text using g.MeasureString but I can't find a method to translate the origin point such that I can find a Rectangle which bounds the text.
Say I have a Point origin at which to draw from, and a StringFormat format with what alignment I wish my string to have. I can find the Size of the string using g.MeasureString(text, font). How do I translate this Point/Size pair into a rectangle which overlaps the g.DrawString(text, font, brush, origin, format) call.
It's difficult to convert c to managed code. You should use .Net code directly if it's available.
For MeasureString, see link Graphics.MeasureString Method
Example:
using System.Diagnostics;
...
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
Font font = new Font("Arial", 16);
SizeF sz = g.MeasureString("Text...", font);
Rectangle rc = new Rectangle(0,0, (int)sz.Width, (int)sz.Height);
Debug.WriteLine(rc.Width.ToString());
Debug.WriteLine(rc.Height.ToString());
//change top/left origin of rectangle
rc.X = 10;
rc.Y = 20;
}
You just need the width and height of text. You can change left/top corner of rectangle.
By the way, the C method gives a rectangle with top/left coordinates at zero, so it's the same information as Size
Edit
This will fit text with word-break flag in to a rectangle whose width is 100. The height of the rectangle is not known. TextRenderer.MeasureText will tell us the height of the rectangle. Top/left corner can be changed, alignment can be changed.
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Font font = new Font("Arial", 10);
string text = "I'm trying to draw a box around a label which has been aligned.";
Size layout = new Size(100, 0);
Size sz = TextRenderer.MeasureText(e.Graphics, text, font, layout,
TextFormatFlags.WordBreak);
Rectangle rc = new Rectangle(new Point(0,0), sz);
e.Graphics.DrawRectangle(Pens.Black, rc);
TextRenderer.DrawText(e.Graphics, text, font, rc,
SystemColors.ControlText, SystemColors.Control, TextFormatFlags.WordBreak);
}
My way is use SetMeasurableCharacterRanges to obtain the region of the whole text.
Consider into OnPaint:
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Font font = new Font("Arial", 16);
string text = "Border of this text";
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
RectangleF area = new RectangleF(0, 0, 246, 84);
sf.SetMeasurableCharacterRanges(new CharacterRange[] { new CharacterRange(0, text.Length) });
Region[] r = g.MeasureCharacterRanges(text, font, area, sf);
Rectangle rf = new Rectangle((int)r[0].GetBounds(g).X, (int)r[0].GetBounds(g).Y, (int)r[0].GetBounds(g).Width, (int)r[0].GetBounds(g).Height);
g.DrawString(text, font, Brushes.Black, area, sf);
g.DrawRectangle(new Pen(Color.Red, 1), rf);
}

How to fill curved area with color in C# Winform?

I want to draw curved area with color(black in my case) in a rectangle.
I tried multiple things FillPie, FillEllipse in OnPaint event but not able to do, I want to draw like thisFill Curved Area
I have tried the below code. but this is not what I want
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics gr = e.Graphics;
int x = 50;
int y = 50;
int width = 100;
int height = 100;
Rectangle rect = new Rectangle(x, y, width / 2, height / 2);
gr.FillRectangle(Brushes.Black, rect);
gr.FillPie(Brushes.White, x, y, width, height, 180, 90);
using (Pen pen = new Pen(Color.Yellow, 1))
gr.DrawArc(pen, x, y, width, height, 180, 90);
}
this code is drawing like this. I dont want to create extra rectangle. MyCode
I'm not 100% sure if this is that what you wanted:
I achieved this by creating a Region with a quarter of the specified rectangle. I then exclude the pie from it using a GraphicsPath. The resulting curve is then filled using Graphics.FillRegion with a black brush:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics gr = e.Graphics;
int x = 50;
int y = 50;
int width = 100;
int height = 100;
Rectangle rect = new Rectangle(x, y, width/ 2, height / 2);
Region r = new Region(rect);
GraphicsPath path = new GraphicsPath();
path.AddPie(x, y, width, height, 180, 90);
r.Exclude(path);
gr.FillRegion(Brushes.Black,r);
}

visual c# - onPaint and transparency

I am making a simple form with two semi-transparent texts
and i put it in a paint event.
only, when I wider the form, the texts turn darker and grainy.
actualy I want the darker color but not the grainy effect.
here is my code snippet:
private void sbfToolBox_Paint(object sender, PaintEventArgs e)
{
System.Drawing.Graphics formGraphics = this.CreateGraphics();
formGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
string drawString = "tekst";
System.Drawing.Font drawFont = new System.Drawing.Font("Arial", 50);
Color color_red = Color.FromArgb(30, 100, 0, 0);
Color color_cyan = Color.FromArgb(30, 0, 100, 100);
System.Drawing.SolidBrush brush_red = new System.Drawing.SolidBrush(color_red);
System.Drawing.SolidBrush brush_cyan = new System.Drawing.SolidBrush(color_cyan);
float x = 0.0F;
float x2 = 20.0F;
float y = 50.0F;
formGraphics.DrawString(drawString, drawFont, brush_red, x, y);
formGraphics.DrawString(drawString, drawFont, brush_cyan, x2, y);
drawFont.Dispose();
brush_red.Dispose();
brush_cyan.Dispose();
formGraphics.Dispose();
}
thanks in advance
Use the Graphics object from PaintEventArgs.
Change
System.Drawing.Graphics formGraphics = this.CreateGraphics();
To
System.Drawing.Graphics formGraphics = e.Graphics;
And remove
formGraphics.Dispose();

Center text output from Graphics.DrawString()

I'm using the .NETCF (Windows Mobile) Graphics class and the DrawString() method to render a single character to the screen.
The problem is that I can't seem to get it centred properly. No matter what I set for the Y coordinate of the location of the string render, it always comes out lower than that and the larger the text size the greater the Y offset.
For example, at text size 12, the offset is about 4, but at 32 the offset is about 10.
I want the character to vertically take up most of the rectangle it's being drawn in and be centred horizontally. Here's my basic code. this is referencing the user control it's being drawn in.
Graphics g = this.CreateGraphics();
float padx = ((float)this.Size.Width) * (0.05F);
float pady = ((float)this.Size.Height) * (0.05F);
float width = ((float)this.Size.Width) - 2 * padx;
float height = ((float)this.Size.Height) - 2 * pady;
float emSize = height;
g.DrawString(letter, new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular),
new SolidBrush(Color.Black), padx, pady);
Yes, I know there is the label control that I could use instead and set the centring with that, but I actually do need to do this manually with the Graphics class.
I'd like to add another vote for the StringFormat object.
You can use this simply to specify "center, center" and the text will be drawn centrally in the rectangle or points provided:
StringFormat format = new StringFormat();
format.LineAlignment = StringAlignment.Center;
format.Alignment = StringAlignment.Center;
However there is one issue with this in CF. If you use Center for both values then it turns TextWrapping off. No idea why this happens, it appears to be a bug with the CF.
To align a text use the following:
StringFormat sf = new StringFormat();
sf.LineAlignment = StringAlignment.Center;
sf.Alignment = StringAlignment.Center;
e.Graphics.DrawString("My String", this.Font, Brushes.Black, ClientRectangle, sf);
Please note that the text here is aligned in the given bounds. In this sample this is the ClientRectangle.
Through a combination of the suggestions I got, I came up with this:
private void DrawLetter()
{
Graphics g = this.CreateGraphics();
float width = ((float)this.ClientRectangle.Width);
float height = ((float)this.ClientRectangle.Width);
float emSize = height;
Font font = new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular);
font = FindBestFitFont(g, letter.ToString(), font, this.ClientRectangle.Size);
SizeF size = g.MeasureString(letter.ToString(), font);
g.DrawString(letter, font, new SolidBrush(Color.Black), (width-size.Width)/2, 0);
}
private Font FindBestFitFont(Graphics g, String text, Font font, Size proposedSize)
{
// Compute actual size, shrink if needed
while (true)
{
SizeF size = g.MeasureString(text, font);
// It fits, back out
if (size.Height <= proposedSize.Height &&
size.Width <= proposedSize.Width) { return font; }
// Try a smaller font (90% of old size)
Font oldFont = font;
font = new Font(font.Name, (float)(font.Size * .9), font.Style);
oldFont.Dispose();
}
}
So far, this works flawlessly.
The only thing I would change is to move the FindBestFitFont() call to the OnResize() event so that I'm not calling it every time I draw a letter. It only needs to be called when the control size changes. I just included it in the function for completeness.
To draw a centered text:
TextRenderer.DrawText(g, "my text", Font, Bounds, ForeColor, BackColor,
TextFormatFlags.HorizontalCenter |
TextFormatFlags.VerticalCenter |
TextFormatFlags.GlyphOverhangPadding);
Determining optimal font size to fill an area is a bit more difficult. One working soultion I found is trial-and-error: start with a big font, then repeatedly measure the string and shrink the font until it fits.
Font FindBestFitFont(Graphics g, String text, Font font,
Size proposedSize, TextFormatFlags flags)
{
// Compute actual size, shrink if needed
while (true)
{
Size size = TextRenderer.MeasureText(g, text, font, proposedSize, flags);
// It fits, back out
if ( size.Height <= proposedSize.Height &&
size.Width <= proposedSize.Width) { return font; }
// Try a smaller font (90% of old size)
Font oldFont = font;
font = new Font(font.FontFamily, (float)(font.Size * .9));
oldFont.Dispose();
}
}
You'd use this as:
Font bestFitFont = FindBestFitFont(g, text, someBigFont, sizeToFitIn, flags);
// Then do your drawing using the bestFitFont
// Don't forget to dispose the font (if/when needed)
Here's some code. This assumes you are doing this on a form, or a UserControl.
Graphics g = this.CreateGraphics();
SizeF size = g.MeasureString("string to measure");
int nLeft = Convert.ToInt32((this.ClientRectangle.Width / 2) - (size.Width / 2));
int nTop = Convert.ToInt32((this.ClientRectangle.Height / 2) - (size.Height / 2));
From your post, it sounds like the ClientRectangle part (as in, you're not using it) is what's giving you difficulty.
You can use an instance of the StringFormat object passed into the DrawString method to center the text.
See Graphics.DrawString Method and StringFormat Class.

Categories