BoltBait.com

Drawing Outlines in a GPU Drawing Plugin

Let's draw some outlines in a Paint.NET plugin


You will need to configure CodeLab to run with "No Selection Clipping" in order to follow this tutorial.


I have not written this tutorial yet, but here's some code to get you started:

// No Selection Clipping
protected override unsafe void OnDraw(IDeviceContext deviceContext)
{
    // preserve background
    deviceContext.DrawImage(Environment.SourceImage);

    // get current selection as a geometry object
    IGeometry outlineGeometry = Environment.Selection.Geometry;

    // create a Direct2D factory
    IDirect2DFactory d2dFactory = this.Services.GetService<IDirect2DFactory>();

    // describe the type of line we will render
    IStrokeStyle myStrokeStyle = d2dFactory.CreateStrokeStyle(
        new StrokeStyleProperties(
            CapStyle.Flat, // start end cap
            CapStyle.Flat, // end end cap
            CapStyle.Flat, // dash end cap
            LineJoin.Miter, // corner type
            10f, // miter limit
            DashStyle.Solid, // line type
            0f, // dash offset
            StrokeTransformType.Normal));

    // make our line 5px wide and apply our selected style
    outlineGeometry = outlineGeometry.Widen(5, myStrokeStyle);

    // create a red brush for drawing our line
    ISolidColorBrush brush = deviceContext.CreateSolidColorBrush(LinearColors.Red);

    // make sure the line is antialiased
    deviceContext.AntialiasMode = AntialiasMode.PerPrimitive; // .Aliased

    // draw the actual line
    deviceContext.FillGeometry(outlineGeometry, brush);
}

Go ahead and press Ctrl+P to preview your effect.


Finishing Up

Once you've got that working, remember to save your script! I wouldn't want you to lose any of your hard work.

"File > Save" your outline.cs file.

If you'd like to make that plugin a permanent part of your Paint.NET installation, read:

How to Build a DLL from a CodeLab script
How to install a DLL into Paint.NET


What's Next?

Now that you know a bit about rendering text and outlines, let's dig a little deeper and design and implement a more complicated effect that renders outlined and filled text. Plus, it adds a UI to our effect.


#region UICode
MultiLineTextboxControl Amount1 = "Paint.NET Rocks!!!"; // [32767] Text
FontFamily Amount2 = "Arial"; // Font
ColorWheelControl Amount3 = ColorBgra.FromBgr(0, 0, 255); // [Red!] Fill Color
ColorWheelControl Amount4 = ColorBgra.FromBgr(0, 0, 0); // [Black!] Outline Color
#endregion
protected override unsafe void OnDraw(IDeviceContext deviceContext)
{
    // preserve background
    deviceContext.DrawImage(Environment.SourceImage);

    // create a Direct2D factory and a Text factory
    IDirect2DFactory d2dFactory = this.Services.GetService<IDirect2DFactory>();
    IDirectWriteFactory textFactory = this.Services.GetService<IDirectWriteFactory>();

    // describe the text we want to render
    ITextFormat textFormat = textFactory.CreateTextFormat(
        Amount2, 
        null, 
        FontWeight.Normal,
        FontStyle.Normal,
        FontStretch.Normal, 
        72);

    ITextLayout textLayout = textFactory.CreateTextLayout(
        Amount1, 
        textFormat, 
        TextLayoutConstants.DefaultMaxWidth, 
        TextLayoutConstants.DefaultMaxHeight);

    IStrokeStyle myStrokeStyle = d2dFactory.CreateStrokeStyle(
        new StrokeStyleProperties(
            CapStyle.Flat, // start end cap
            CapStyle.Flat, // end end cap
            CapStyle.Flat, // dash end cap
            LineJoin.Miter, // corner type
            10f, // miter limit
            DashStyle.Solid, // line type
            0f, // dash offset
            StrokeTransformType.Normal));

    // create a geometry object from our text
    IGeometry textGeometry = d2dFactory.CreateGeometryFromTextLayout(textLayout, 80, 50);

    // create a red brush for drawing our text
    ISolidColorBrush fillBrush = deviceContext.CreateSolidColorBrush(Amount3);

    // create a black brush for drawing the outline
    ISolidColorBrush outlineBrush = deviceContext.CreateSolidColorBrush(Amount4);

    // make sure the line is anti-aliased
    deviceContext.AntialiasMode = AntialiasMode.PerPrimitive; // .Aliased

    // draw the actual outline of the text
    deviceContext.DrawGeometry(textGeometry, outlineBrush, 4, myStrokeStyle);

    // fill the text
    deviceContext.FillGeometry(textGeometry, fillBrush);

    // you can do the last two lines in opposite order for fatter outlines
}

Adding a slider to control the font size and a slider to control the outline thickness is an exercise left up to the reader.


What's Next?

Head back to the Tutorial Index to learn something else



Donate

The best way to say "Thanks" for teaching you something here, is to fill out this form. It uses PayPal to process your donation. You don't need a PayPal account, just a credit/debit card will do. If PayPal doesn't work for you, no need to worry--just enjoy the tutorials for free!

$
Thank you for your donation. I don't get many, so you can be sure I really appreciate yours!



 

 
 

News


CodeLab 6.13 Released
(November 17, 2024)
This latest release of CodeLab for Paint.NET includes the ability to write GPU accelerated plugins.
More...

Double-Six Dominoes 3.1
(May 10, 2021)
This long-awaited refresh of the most popular dominoes game on Download.com is now available!
More...

HTML Editor 1.5 Released
(March 31, 2016)
This latest release is a complete rewrite adding a wysiwyg editor mode and a much improved UI.
More...