• 0

[C#] Drawing outline text


Question

Recommended Posts

  • 0

It's pretty easy.

From Windows Forms Programming in C# by Chris Sells

GraphicsPath GetStringPath( string s, float dpi, RectangleF rect, Font font, StringFormat format)
{
    GraphicsPath path = new GraphicsPath();
    // Convert font size into appropriate coordinates
    float emSize = dpi * font.SizeInPoints / 72;
    path.AddString(s, font.FontFamily, (int)font.Style, emSize, rect, format);

    return path;
}

void Form_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    string s = "Outline";
    RectangleF rect = this.ClientRectangle;
    Font font = this.Font;
    StringFormat format = StringFormat.GenericTypographic;
    float dpi = g.DpiY;
    using( GraphicsPath = GetStringPath(s, dpi, rect, font, format) )
    {
        g.DrawPath(Pens.Black, path);
    }
}

  • 0
I want it to have an inner white color and a shadow. Do you think it is possible ?

It's possible.

In the paint event.

  	Graphics g = e.Graphics;
  	string s = "Outline";
  	RectangleF rect = this.ClientRectangle;
  	Font font = this.Font;
  	StringFormat format = StringFormat.GenericTypographic;
  	float dpi = g.DpiY;
  	using( GraphicsPath path = GetStringPath(s, dpi, rect, font, format) )
  	{	
    g.SmoothingMode = SmoothingMode.AntiAlias;
    RectangleF off = rect;
    off.Offset( 5, 5 );
    using( GraphicsPath offPath = GetStringPath(s, dpi, off, font, format) )
    {
    	Brush b = new SolidBrush(Color.FromArgb(100, 0, 0, 0));
    	g.FillPath(b, offPath);
    	b.Dispose();
    }
    g.FillPath(Brushes.White, path);
    g.DrawPath(Pens.Black, path);
  	}

Edited by weenur
  • 0
:laugh: Thanks a lot weenur - that's really close  :D Can I make the shadow even more smooth? Is there a way I can control the shadow width?

585273695[/snapback]

You want that with ice cream? :p

You basically want a blur on the shadow, no?

Edited by weenur
  • 0
Yes - I'm really sorry that I bother you  :blush:  :rolleyes: I didn't mean to do it. I was too rude  :unsure:  it's not urgent so if you have time I'll apprreciate your answer.

585274184[/snapback]

No sweat. I'm just giving you grief. ;)

I should be able to have an example for you as soon as I get some time. I also need to figure out how to convert a region to a bitmap. <anyone?>

  • 0

I'm converting the GraphicsPath to a Region, and then from a Region to a Bitmap to perform raster operations on it. I see what Bob is doing. That's cool. The guy is a guru. I was actually going to do a gaussian blur on the shadow and make it adjustable. I'm just drawing a blank on how to make a Bitmap from a Region.

Region class

  • 0
I'm converting the GraphicsPath to a Region, and then from a Region to a Bitmap to perform raster operations on it. I see what Bob is doing. That's cool. The guy is a guru. I was actually going to do a gaussian blur on the shadow and make it adjustable. I'm just drawing a blank on how to make a Bitmap from a Region.

Region class

585276170[/snapback]

Yes but a Region is simply that - a region. So to turn it into a Bitmap you need to use the region on a Bitmap e.g. Create a new Bitmap of the appropriate dimensions then use Graphics.FillRegion with a suitable Brush. Or am I missing something?

  • 0
Yes but a Region is simply that - a region. So to turn it into a Bitmap you need to use the region on a Bitmap e.g. Create a new Bitmap of the appropriate dimensions then use Graphics.FillRegion with a suitable Brush. Or am I missing something?

585276240[/snapback]

See... that's what I couldn't remember. :D Thanks. It's been a while since I've done any GDI/+ to any extent.

  • 0
See... that's what I couldn't remember. :D Thanks. It's been a while since I've done any GDI/+ to any extent.

585276814[/snapback]

Funny...you virtually answered your own question with your previous post when you said "I'm just drawing a blank on how to make a Bitmap from a Region."! :p

  • 0
Funny...you virtually answered your own question with your previous post when you said "I'm just drawing a blank on how to make a Bitmap from a Region."!  :p

585276872[/snapback]

lmao! I didn't even catch that. I've been staying up too late playing World of Warcraft. :)

  • 0

OK, yyy. If this doesn't do it for you, use Bob Powell's version. You can, of course, modify it to your liking, and set it up to be configurable.

First, add the Filters.cs file to your project. ( get it here )

<edit> you should dispose of the Regions when you're done, as well as the Bitmap.

// In the paint handler
  	Graphics g = e.Graphics;
  	string s = "Outline";
  	Font font = this.Font;
  	RectangleF rect = this.ClientRectangle;
  	StringFormat format = StringFormat.GenericTypographic;
  	float dpi = g.DpiY;
  	using( GraphicsPath path = GetStringPath(s, dpi, rect, font, format) )
  	{	
    g.SmoothingMode = SmoothingMode.AntiAlias;
    RectangleF off = rect;
    off.Offset( 2, 2 );
    Bitmap bmp = null;
    using( GraphicsPath offPath = GetStringPath(s, dpi, off, font, format) )
    {
    	bmp = new Bitmap((int)rect.Width, (int)rect.Height);
    	Graphics g2 = Graphics.FromImage(bmp);
    	g2.CompositingMode = CompositingMode.SourceOver;
    	g2.CompositingQuality = CompositingQuality.HighQuality;
    	g2.SmoothingMode = SmoothingMode.AntiAlias;
    	Brush b = new SolidBrush(Color.FromArgb(200, 0, 0, 0));
    	Region r = new Region(offPath);
    	Region rxor = new Region(rect);
    	g2.FillRegion(SystemBrushes.Control, rxor);
    	rxor.Xor(r);
    	g2.FillRegion(b, r);
    	BitmapFilter.GaussianBlur(bmp, 4);
    	BitmapFilter.GaussianBlur(bmp, 4);
    	BitmapFilter.GaussianBlur(bmp, 4);
    	BitmapFilter.GaussianBlur(bmp, 4);
    	BitmapFilter.GaussianBlur(bmp, 4);
    	b.Dispose();
    	g2.Dispose();
    }
    if( bmp != null )
    {
    	// draw the image
    	g.DrawImage(bmp, off);
    }
    g.FillPath(Brushes.White, path);
    g.DrawPath(Pens.Black, path);
  	}
  }

  • 0

Wow :laugh: it works great :cool:

I just have 2 questions:

1. Are you sure that this source code (and the filters.cs file) are free to use and ditrobute ? I need this code for a freeware application which I plan to distrobute freely with the source code so I need to be sure.

2. This is not so important but I was wondering if there's a way to reduce the Memory usage of that code - it raises the application's Memory usage by about 3 MB I think. It's not that bad but I just wonder.

Thanks again for helping me :)

  • 0

1. Ask the author. I'm sure that as long as you give credit where credit is due, you'll be fine. He is posting it for teaching purposes.

2. I'd have to look more closely at his code. I'm fairly certain that he's managed his memory properly. You could try doing a GC.Collect() at the end of the Paint event. I kind of doubt it'll help, but you never know. Is that memory footprint in release mode, or debug?

  • 0
1. Ask the author. I'm sure that as long as you give credit where credit is due, you'll be fine. He is posting it for teaching purposes.

2. I'd have to look more closely at his code. I'm fairly certain that he's managed his memory properly. You could try doing a GC.Collect() at the end of the Paint event. I kind of doubt it'll help, but you never know. Is that memory footprint in release mode, or debug?

585281673[/snapback]

Ok, I'll ask him.

You don't need to look at the code - that's Ok. I was just wondering if there's a fast way to do it but you are right - probably the code's writer already thought of the memory issue. It isn't that bad after all. I think it is in the release mode.

  • 0
I can't ask the "Windows Forms Programming in C#"  book's author - I don't have his E-mail and I don't think he'll allow me to use that code since it was written in a book. Nevermind - I'll do something else.

585285520[/snapback]

Uh... use it.

Permission is granted to anyone to use this software for any purpose, including commercial applications, subject to the following restrictions

1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is requested, as shown here:

Portions copyright ? 2003 Chris Sells (http://www.sellsbrothers.com/).

 

2. No substantial portion of this source code may be redistributed without the express written permission of the copyright holders, where "substantial" is defined as enough code to be recognizably from this code.

  • 0
2. No substantial portion of this source code may be redistributed without the express written permission of the copyright holders, where "substantial" is defined as enough code to be recognizably from this code.

It's pretty explicit - if you are going to distribute the source of your project and it contains a "recognisable portion" of the books sample source code, then you will need to obtain permission from Chris Sells. So just drop him a mail at [email protected] - he may even give you some advice on the memory footprint.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • You're right that it does not follow the plain meaning of the word, but in this context, it is a legal term defined in 49 U.S.C. Kind of how "wire fraud" laws apply even if a physical wire was not used. Given that it is codified in law, and it isn't just automotive journalists that don't understand evolving technology, I highly doubt congress would change a well understood term just because technology makes the term slightly less actuate.
    • This is exactly why I keep saying we are not ready for human free self-driving. These little "bugs" are may seem like random one-offs. There was also the Waymo that drove between police with drawn weapons and the suspect they were pointing them at. From a software perspective it is easy to understand how those extremely rare situations may not have been programed for, but that is the point. If AI needs to be told to watch out for every possible contingency, then it can never be successful. There will always be the possibility of a first encounter that the AI needs to understand to avoid.
    • TeraCopy 4.0 Final by Razvan Serea TeraCopy is a compact program designed to copy and move files at the maximum possible speed, also providing you with a lot of features. Copy files faster. TeraCopy uses dynamically adjusted buffers to reduce seek times. Asynchronous copy speeds up file transfer between two physical hard drives. Pause and resume transfers. Pause copy process at any time to free up system resources and continue with a single click. Error recovery. In case of copy error, TeraCopy will try several times and in the worse case just skips the file, not terminating the entire transfer. Interactive file list. TeraCopy shows failed file transfers and lets you fix the problem and recopy only problem files. Shell integration. TeraCopy can completely replace Explorer copy and move functions, allowing you work with files as usual. TeraCopy is free for non-commercial use only. For commercial use you need to buy a license. The paid version of the program includes the following features: Copy/move to your favorite folders. Save reports as HTML and CSV files. Select files with the same extension/folder. Remove the selected files from the copy queue. Download: TeraCopy 4.0 | 14.6MB (Freeware, paid upgrade available) View: TeraCopy Website | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • Recycle Bin has been broken for literal YEARS now. The setting to delete files older than 30 days from the bin which is on by default doesn't even work. I have files older than 4 months in it and they are just there still...
  • Recent Achievements

    • Week One Done
      Eurosoft10 earned a badge
      Week One Done
    • One Month Later
      Eurosoft10 earned a badge
      One Month Later
    • One Year In
      Skeet Campbell earned a badge
      One Year In
    • One Month Later
      Sharbel earned a badge
      One Month Later
    • First Post
      BizSAR earned a badge
      First Post
  • Popular Contributors

    1. 1
      +primortal
      586
    2. 2
      +Edouard
      187
    3. 3
      Michael Scrip
      74
    4. 4
      PsYcHoKiLLa
      72
    5. 5
      neufuse
      69
  • Tell a friend

    Love Neowin? Tell a friend!