xod

Unfinished plugins

Recommended Posts

@Djisves the plugin is not finished yet.

But if you want it in this state: 

 

OutlinedGradientText.zip

 

When running the plugin, if you did not type any text and choose a gradient the plugin crashes.

System.OutOfMemoryException: Out of memory.

Edited by xod
  • Upvote 1

Share this post


Link to post
Share on other sites
23 hours ago, xod said:

if you did not type any text and choose a gradient the plugin crashes.

 

I fixed mine.

 

You can copy my fix to yours @xod then I think you're ready to publish.

 

BTW, your code still has the problem Eli noticed (about selections).  You can copy my fix for that as well.

 

Here is the complete script with all bugs fixed:

 

Spoiler

// Name: Outlined / Gradient text
// Submenu: Text Formations
// Author: xod & BoltBait
// Title: Outlined / Gradient text
// Version: 1.0
// Desc: Draws outlined, gradient filled text
// Keywords: text|gradient|outline
// URL:
#region UICode
MultiLineTextboxControl Amount1 = "TEST"; // [1,32767] Text
FontFamily Amount2 = new FontFamily("Arial"); // Font
IntSliderControl Amount3 = 72; // [2,400] Font size
IntSliderControl Amount4 = 8; // [0,100] Outline size
ColorWheelControl Amount5 = ColorBgra.FromBgr(0,0,0); // [PrimaryColor] Outline color
ColorWheelControl Amount6 = ColorBgra.FromBgr(255,255,255); // [SecondaryColor] Fill color
ListBoxControl Amount7 = 0; // Fill Type|Solid Fill|Vertical Gradient|Horizontal Gradient|Diagonal Gradient|Reverse Diagonal Gradient
ColorWheelControl Amount8 = ColorBgra.FromBgr(0,0,0); // [PrimaryColor] {!Amount7} Secondary Fill Color
DoubleSliderControl Amount9 = 1.0; // [0,1] {!Amount7} Reflection point
PanSliderControl Amount10 = Pair.Create(0.000,0.000); // Location
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    Rectangle sel = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
    dst.CopySurface(src,rect.Location,rect);

    int adrX = (int)Math.Round((((Amount10.First + 1) / 2) * (sel.Right - sel.Left)) + sel.Left);
    int adrY = (int)Math.Round((((Amount10.Second + 1) / 2) * (sel.Bottom - sel.Top)) + sel.Top);

    String text = Amount1;
    if (text == "") text = " ";
    FontFamily font = Amount2;
    int txtSize = Amount3;
    Color fontColor = Amount6;
    int outlineSize = Amount4;
    Color outlineColor = Amount5;
    byte opacity = 255;

    Graphics g = new RenderArgs(dst).Graphics;
    g.SmoothingMode = SmoothingMode.AntiAlias;
    g.TextRenderingHint = TextRenderingHint.AntiAlias;

    StringFormat format = new StringFormat();
    format.Alignment = StringAlignment.Center;
    format.LineAlignment = StringAlignment.Center;

    ColorBgra FillColor1 = Amount6;
    ColorBgra FillColor2 = Amount8;    
    if (Amount7 == 0) FillColor2 = FillColor1;
    
    SizeF stringSize = new SizeF();
    stringSize = g.MeasureString(text, new Font(Amount2, Amount3));
    
    int GStartX = 0;
    int GStartY = 0;
    int GEndX = 1;
    int GEndY = 1;
    
    switch (Amount7)
    {
        case 1:
            GStartX = adrX;
            GEndX = adrX;
            GStartY = (int)(adrY - stringSize.Height / 2);
            GEndY = (int)(adrY + stringSize.Height / 2);
            break;
        case 2:
            GStartX = (int)(adrX - stringSize.Width / 2);
            GEndX = (int)(adrX + stringSize.Width / 2);
            GStartY = adrY;
            GEndY = adrY;
            break;
        case 3:
            GStartX = (int)(adrX - stringSize.Width / 2);
            GStartY = (int)(adrY - stringSize.Height / 2);
            GEndX = (int)(adrX + stringSize.Width / 2);
            GEndY = (int)(adrY + stringSize.Height / 2);
            break;
        case 4:
            GStartX = (int)(adrX + stringSize.Width / 2);
            GStartY = (int)(adrY - stringSize.Height / 2);
            GEndX = (int)(adrX - stringSize.Width / 2);
            GEndY = (int)(adrY + stringSize.Height / 2);
            break;
        default:
            break;
    }
    using (GraphicsPath path = new GraphicsPath())
    using (Pen outlinePen = new Pen(Color.FromArgb(opacity, outlineColor), outlineSize))
    using (LinearGradientBrush myGradientBrush = new LinearGradientBrush(new Point(GStartX,GStartY),new Point(GEndX,GEndY), FillColor1, FillColor2))
    {
        myGradientBrush.SetBlendTriangularShape((float)Amount9, 1.0f);
        g.Clip = new Region(rect);
        FontFamily myFont;
        try
        {
            myFont = new FontFamily(font.Name);
        }
        catch
        {
            myFont = new FontFamily("Arial");
        }
        outlinePen.LineJoin = LineJoin.Round;
        path.AddString(text, myFont, (int)FontStyle.Regular, g.DpiY * txtSize / 72, new PointF(adrX, adrY), format);
        if (Amount4 > 0)
        {
            g.DrawPath(outlinePen, path);
        }
        g.FillPath(myGradientBrush, path);
    }
    g.Dispose();
}

 

 

Minus your Intensity slider, which really isn't necessary as the user can simply select different colors and get the same effect.  I prefer a smaller UI whenever possible.

Share this post


Link to post
Share on other sites

BTW @BoltBait

This is how I spent my Sun Afternoon

After you updated your code I tried to rebuild the DLL

This is one of those "Hard to Believe" Issues. This is the error message I kept getting

pnhtjG.png

 

I know the file does not exist on the desktop. I am building it. 
I know the file is not in use - it hasn't been built yet. 
Even trying to build under a different name results in the same error message.
There are no other reported errors in the dialogue box
At first I thought it might be Codelab 3.4 so I removed it and re installed 3.3
This did not resolve the issue so I reinstalled 3.4 and still continue to get the error message. 
I uninstalled paint and reinstalled with codelab 3.3 - still got the same error message
Renamed an older dll and it worked fine. 
Deleting the files and rebuilding still receives the error. Rebooting still receives the error.
After building 30 plugins I thought I knew what I was doing. Just recently I was exporting a few to Visual Studio 2017 and recompiling them for the experience and everything was working fine. After trying to build this recent posted scipt from the forum - I consistently receive this error from Codelab.

I find it hard to believe that it is only happening to me and has yet to be reported. I was quite reluctant to post this rant but thought you should know. Something very strange about this plugin. This was the first time I have ever used the Ctrl-I keystroke in Codelab.

I was having the same problem with your other post about selecting and filling with color. After your update, I tried to rebuild, but all I got was this same error message.

 

B)

Share this post


Link to post
Share on other sites

You changed the Author line.  Change it back and try again.

 

The script I posted compiles.  I can not guarantee that any changes you make will compile.

 

EDIT: The real trouble is the backslash character "\".  That is a special character to the compiler and you haven't used it correctly.  To fix your problem you can either use two in a row, "\\" or simply change it into a forward slash "/".

 

Edited by BoltBait
Added detailed explanation.
  • Like 1

Share this post


Link to post
Share on other sites
1 minute ago, AndrewDavid said:

I thought it would be OK in a comment line.

 

Normally it would be OK in a comment line.

 

However, comments in CodeLab are special.  The information in them is used when compiling a DLL file.

Share this post


Link to post
Share on other sites

Hello,

 

This is a code which works in Codelab 3.4 but I can't preview nor build it.

 

preview

hlibert_err1.png

 

build

hlibert_err2.png

(Same message had AndrewDavid but I have no specific characters in my comments)

 

I suppose the problem is linked with the loading of the palette. It stops working when I add this feature.

 

Spoiler

 


// Name:Hilbert Curve
// Submenu:Texture
// Author:MadJik (Jean-Claude JAY)
// Title:Hilbert Curve
// Version:0.2
// Desc:Hilbert Curve (ref web: http://csharphelper.com/blog/2014/07/draw-a-hilbert-curve-fractal-in-c/ )
// Keywords:hilbert|texture|fractal|curve|maze
// URL: http://forums.getpaint.net/index.php?showtopic=7186
#region UICode
IntSliderControl Amount1 = 4; // [1,10] Depth
DoubleSliderControl Amount2 = 95; // [1,100] Size in %
DoubleSliderControl Amount3 = 0; // [1,100] Single Cell Size (0=auto)
IntSliderControl Amount4 = 18; // [1,100] Brush width
IntSliderControl Amount5 = 255; // [0,255] Transparency
ListBoxControl Amount6 = 0; // Line style|Solid|Dash|Dash Dot|Dash Dot Dot|Dot
ListBoxControl Amount7 = 3; // End caps style|None|Round|Triangle|Square
CheckboxControl Amount8 = false; // [0,1] Antialiasing
CheckboxControl Amount9 = true; // [0,1] Use colors from palette
#endregion

private float LastX, LastY, MapSize;
private int depth, palcolor;
private Pen p;
private ColorBgra[] CurrentColors = null;

// Draw a Hilbert curve.
private void Hilbert(Graphics gr, int depth, float dx, float dy)
{
    if (depth > 1) Hilbert(gr, depth - 1, dy, dx);
    DrawRelative(gr, dx, dy);
    if (depth > 1) Hilbert(gr, depth - 1, dx, dy);
    DrawRelative(gr, dy, dx);
    if (depth > 1) Hilbert(gr, depth - 1, dx, dy);
    DrawRelative(gr, -dx, -dy);
    if (depth > 1) Hilbert(gr, depth - 1, -dy, -dx);
    if (IsCancelRequested) return;
}

// Draw the line (LastX, LastY)-(LastX + dx, LastY + dy) and
// update LastX = LastX + dx, LastY = LastY + dy.
private void DrawRelative(Graphics gr, float dx, float dy)
{
    if (Amount9)
    {
        p.Color = Color.FromArgb((byte)Amount5, (Color)CurrentColors[palcolor++]);
        if (palcolor>95) palcolor=0;
    }
    gr.DrawLine(p, LastX, LastY, LastX + dx, LastY + dy);
    LastX = LastX + dx;
    LastY = LastY + dy;
}

void PreRender(Surface dst, Surface src)
{
    // copy original image
    dst.CopySurface(src);

    // load palette
    CurrentColors = new ColorBgra[96];
    IReadOnlyList<ColorBgra> Palette = ServiceProviderExtensions.GetService<IPalettesService>(Services).CurrentPalette;
    for (int i = 0; i<96; i++)
    {
        CurrentColors[i]=Palette[i];
    }
    palcolor = 0;

    // Get the parameters.
    float total_length, start_x, start_y, start_length;
    depth = Amount1;
    MapSize = (float)Amount2 / 100.0f;

    // See how big we can make the curve.
    if (src.Height < src.Width)
    {
        total_length = MapSize * (float)src.Height;
    }
    else
    {
        total_length = MapSize * (float)src.Width;
    }

    start_x = (src.Width - total_length) / 2f;
    start_y = (src.Height - total_length) / 2f;

    // Compute the side length for this level.
    if (Amount3==0)
    {

        start_length = (float)(total_length / (Math.Pow(2, depth) - 1));
    }
    else
    {
        start_length = (float)Amount3;
    }

    ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
    PrimaryColor.A = (byte)Amount5;
    p = new Pen(PrimaryColor, Amount4);

    if (Amount7 > 0)
    {
        switch (Amount7)
        {
            case 1:
                p.StartCap = System.Drawing.Drawing2D.LineCap.Round;
                p.EndCap = System.Drawing.Drawing2D.LineCap.Round;
                break;
            case 2:
                p.StartCap = System.Drawing.Drawing2D.LineCap.Triangle;
                p.EndCap = System.Drawing.Drawing2D.LineCap.Triangle;
                break;
            case 3:
                p.StartCap = System.Drawing.Drawing2D.LineCap.Square;
                p.EndCap = System.Drawing.Drawing2D.LineCap.Square;
                break;
            default:
                break;
        }
    }
    if (Amount6 > 0)
    {
        switch (Amount6)
        {
            case 0: // Solid
                p.DashStyle = DashStyle.Solid;
                break;
            case 1: // Dash
                p.DashStyle = DashStyle.Dash;
                break;
            case 2: // DashDot
                p.DashStyle = DashStyle.DashDot;
                break;
            case 3: // DashDotDot
                p.DashStyle = DashStyle.DashDotDot;
                break;
            case 4: // Dot
                p.DashStyle = DashStyle.Dot;
                break;
        }
    }

    //Graphics gr = new RenderArgs(dst).Graphics;
    using (Graphics gr = new RenderArgs(dst).Graphics)
    {
        if (Amount8) gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        // Draw the curve.
        LastX = (int)start_x;
        LastY = (int)start_y;
        Hilbert(gr, depth, 0, start_length);
    }
}

// Here is the main render loop function
void Render(Surface dst, Surface src, Rectangle rect)
{
}

 

 

 

 

 

Share this post


Link to post
Share on other sites

There are 2 bugs in your code:

 

1 hour ago, MadJik said:

DoubleSliderControl Amount3 = 0; // [1,100] Single Cell Size (0=auto)

 

Change your minim slider amount to 0.

 

DoubleSliderControl Amount3 = 0; // [0,100] Single Cell Size (0=auto)

 

and

 

1 hour ago, MadJik said:

IReadOnlyList<ColorBgra> Palette = ServiceProviderExtensions.GetService<IPalettesService>(Services).CurrentPalette;

 

The next build of CodeLab would have caught this error.  Simply change to:

 

IReadOnlyList<ColorBgra> Palette = PaintDotNet.ServiceProviderExtensions.GetService<IPalettesService>(Services).CurrentPalette;

 

Share this post


Link to post
Share on other sites

This effect was created in VisualStudio only to understand how things work.
It's about ConfigToken, ConfigDialog, InitTokenFromDialog, InitDialogFromToken, and so on.
So it can't be really considered as a plugin. Found in Effects > Render submenu.

 

TiGSckB.png

 

Download

Edited by xod
  • Like 1
  • Upvote 2

Share this post


Link to post
Share on other sites

Spaced / Outlined text it only supports 32 characters.

 

Spoiler

// Name: SpacedOutlinedText
// Submenu: Text Formations
// Author: xod
// Title: Spaced / Outlined Text
// Version: 1.0
// Desc:
// Keywords:
// URL:

#region UICode
MultiLineTextboxControl Amount1 = "TEST"; // [1,255]
FontFamily Amount2 = new FontFamily("Arial"); // Font
CheckboxControl Amount3 = false; // [0,1] Bold
CheckboxControl Amount4 = false; // [0,1] Italic
IntSliderControl Amount5 = 150; // [10,400] Size
ColorWheelControl Amount6 = ColorBgra.FromBgr(100,255,255); // [SecondaryColor] Fill color
PanSliderControl Amount7 = Pair.Create(0.000,0.000); // Offset space X, Y
ColorWheelControl Amount8 = ColorBgra.FromBgr(0,100,0); // [PrimaryColor] Outline color
IntSliderControl Amount9 = 3; // [0,100] Outline depth
CheckboxControl Amount10 = false; // [0,1] Outline over text
PanSliderControl Amount11 = Pair.Create(0.000,0.000); // Location
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    Rectangle sel = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
    dst.CopySurface(src,rect.Location,rect);

    int offsetX = (int)Math.Round((Amount7.First * (sel.Right - sel.Left) / 2));
    int offsetY = (int)Math.Round((Amount7.Second * (sel.Bottom - sel.Top) / 2));
    byte opacity = 255;
    string measureString = Amount1;
    int numChars = measureString.Length;
    Color outlineColor = Amount8;
    float outlineSize = (float)Amount9;
    
    FontStyle myStyle = FontStyle.Regular;
    if (Amount3) myStyle |= FontStyle.Bold;
    if (Amount4) myStyle |= FontStyle.Italic;

    CharacterRange[] characterRanges = new CharacterRange[numChars];
    for (int i = 0; i < numChars; i++) characterRanges[i] = new CharacterRange(i, 1);

    Region[] stringRegions = new Region[numChars];
    StringFormat stringFormat = new StringFormat();
    stringFormat.FormatFlags = StringFormatFlags.NoClip;
    stringFormat.SetMeasurableCharacterRanges(characterRanges);
    stringFormat.Alignment = StringAlignment.Center;

    using(SolidBrush solidBrush = new SolidBrush(Color.FromArgb(opacity, Amount6)))
    using (GraphicsPath path = new GraphicsPath())
    using (Pen outlinePen = new Pen(Color.FromArgb(opacity, outlineColor), outlineSize))
    {
        Graphics g = new RenderArgs(dst).Graphics;
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.TextRenderingHint = TextRenderingHint.AntiAlias;
        g.Clip = new Region(rect);

        Font stringFont;
        try
        {
            stringFont = new Font(Amount2.Name, Amount5, myStyle);
        }
        catch
        {
            stringFont = new Font("Arial", Amount5);
        }

        SizeF size = g.MeasureString(measureString, stringFont);
        RectangleF layoutRect = new RectangleF(0.0f, 0.0f, size.Width, size.Height);

        int col = (int)Math.Round(((Amount11.First + 1) / 2) * (sel.Right - sel.Left) + sel.Left - size.Width / 2);
        int row = (int)Math.Round(((Amount11.Second + 1) / 2) * (sel.Bottom - sel.Top) + sel.Top - size.Height / 2);

        stringRegions = g.MeasureCharacterRanges(measureString, stringFont, layoutRect, stringFormat);
        FontFamily myFont = new FontFamily(Amount2.Name);
        for (int index = 0; index < numChars; index++)
        {
            Region region = stringRegions[index] as Region;
            RectangleF rectChr = region.GetBounds(g);
            rectChr.Offset(col + offsetX * index, row + offsetY * index);
            g.DrawString(measureString.Substring(index, 1), stringFont, solidBrush, rectChr, stringFormat);

            outlinePen.LineJoin = LineJoin.Round;
            path.AddString(measureString.Substring(index, 1), myFont, (int)myStyle, g.DpiY * Amount5 / 72, rectChr, stringFormat);
        }
        if (Amount9 > 0)
        {
            g.DrawPath(outlinePen, path);
        }
        if (!Amount10)
        {
            g.FillPath(solidBrush, path);
        }
        g.Dispose();
    }
}

 

 

Edited by xod

Share this post


Link to post
Share on other sites

Your fontStyles function can just be put inline, like this:

 

FontStyle myStyle = FontStyle.Regular;
if (Amount3) myStyle |= FontStyle.Bold;
if (Amount4) myStyle |= FontStyle.Italic;

 

  • Like 1
  • Upvote 1

Share this post


Link to post
Share on other sites

Gradient shapes.

Spoiler

// Name: GradientShapes
// Submenu: Render
// Author: xod
// Title: GradientShapes
// Version: 1.0
// Desc:
// Keywords:
// URL:
// Help:

#region UICode
IntSliderControl Amount1 = 6; // [3,10] Sides
IntSliderControl Amount2 = 250; // [3,1000] Size
IntSliderControl Amount3 = 2; // [0,100] Border
AngleControl Amount4 = 0; // [-180,180] Angle
ColorWheelControl Amount5 = ColorBgra.FromBgr(255,0,0); // [Blue] First color
ColorWheelControl Amount6 = ColorBgra.FromBgr(225,105,65); // [RoyalBlue] Second color
ColorWheelControl Amount7 = ColorBgra.FromBgr(235,206,135); // [SkyBlue] Center color
ColorWheelControl Amount8 = ColorBgra.FromBgr(255,0,0); // [Blue] Border color
PanSliderControl Amount9 = Pair.Create(0.000,0.000); // Reflection point
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    Rectangle sel = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
    dst.CopySurface(src, rect.Location, rect);
    
    Point center = new Point(sel.Width/2 + sel.Left, sel.Height/2 + sel.Top);
    int sides = Amount1;
    int radius = Amount2;
    int width = Amount3;
    int angle = (int)Amount4;
    int rpx = (int)Math.Round((((Amount9.First + 1) / 2) * (sel.Right - sel.Left)) + sel.Left);
    int rpy = (int)Math.Round((((Amount9.Second + 1) / 2) * (sel.Bottom - sel.Top)) + sel.Top);

    ColorBgra c1 = Amount5;//first color
    ColorBgra c2 = Amount6;//second color
    ColorBgra cc = Amount7;//center color
    ColorBgra bc = Amount8;//border color

    using (RenderArgs ra = new RenderArgs(dst))
    {
        Graphics g = ra.Graphics;
        g.Clip = new Region(rect);
        g.SmoothingMode = SmoothingMode.AntiAlias;

        PointF[] vertices = CalculateVertices(sides, radius, angle, center);
        using(Pen myPen = new Pen(bc, width))
        {
            myPen.LineJoin = LineJoin.Round;
            using (PathGradientBrush pgrbr = new PathGradientBrush(vertices))
            {
                pgrbr.CenterPoint = new Point(rpx, rpy);
                pgrbr.CenterColor = cc;
                switch (sides)
                {
                    case 3:
                        pgrbr.SurroundColors = new Color[]
                        {
                            c1, c2, c1,
                        };
                        break;

                    case 4:
                        pgrbr.SurroundColors = new Color[]
                        {
                            c1, c2, c1, c2
                        };
                        break;

                    case 5:
                        pgrbr.SurroundColors = new Color[]
                        {
                            c1, c2, c1, c2, c1
                        };
                        break;

                    case 6:
                        pgrbr.SurroundColors = new Color[]
                        {
                            c1, c2, c1, c2, c1, c2
                        };
                        break;

                    case 7:
                        pgrbr.SurroundColors = new Color[]
                        {
                            c1, c2, c1, c2, c1, c2, c1
                        };
                        break;

                    case 8:
                        pgrbr.SurroundColors = new Color[]
                        {
                            c1, c2, c1, c2, c1, c2, c1, c2
                        };
                        break;
                    case 9:
                        pgrbr.SurroundColors = new Color[]
                        {
                            c1, c2, c1, c2, c1, c2, c1, c2, c1
                        };
                        break;
                    case 10:
                        pgrbr.SurroundColors = new Color[]
                        {
                            c1, c2, c1, c2, c1, c2, c1, c2, c1,c2
                        };
                        break;
                }
                g.FillPolygon(pgrbr, vertices);
            }
            if(Amount3 != 0)//outline shape
            {
                g.DrawPolygon(myPen, vertices);
            }
        }
        g.Dispose();
    }
}

private PointF[] CalculateVertices(int Sides, int Radius, int startingAngle, Point Center)
{
    List<PointF> points = new List<PointF>();
    float step = 360.0f / Sides;
    float Angle = startingAngle;
    for (double i = startingAngle; i < startingAngle + 360.0; i += step)
    {
        points.Add(DegreesToXY(Angle, Radius, Center));
        Angle += step;
    }
    return points.ToArray();
}

private PointF DegreesToXY(float degrees, float radius, Point Origin)
{
    PointF xy = new PointF();
    double radians = degrees * Math.PI / 180.0;
    xy.X = (float)Math.Cos(radians) * radius + Origin.X;
    xy.Y = (float)Math.Sin(-radians) * radius + Origin.Y;
    return xy;
}

 

 

GradientShapes.zip

  • Upvote 1

Share this post


Link to post
Share on other sites

i just like rotation angle:

Gradient_Shapes200.gif

 

The gradient is on the angle/corner. But it isn't balanced with a odd number of angles (ex: triangle has two gradient with first color to two angles and only one with Second color to the third angle). Could you add an option to say first color gradient ends on angle and second color gradient end on the median of the side?

Share this post


Link to post
Share on other sites

@xod

 

You could go over 10 sides...

Spoiler

...
    ColorBgra c1 = Amount5;//first color
    ColorBgra c2 = Amount6;//second color
    ColorBgra cc = Amount7;//center color
    ColorBgra bc = Amount8;//border color
    Color[] Ct = new Color[sides];
    bool colswitch = true;
    for (int i = 0;i<sides;i++)
    {
        Ct[i] = colswitch?c1:c2;
        colswitch = !colswitch;
    }

    using (RenderArgs ra = new RenderArgs(dst))
    {
        Graphics g = ra.Graphics;
        g.Clip = new Region(rect);
        g.SmoothingMode = SmoothingMode.AntiAlias;

        PointF[] vertices = CalculateVertices(sides, radius, angle, center);
        using(Pen myPen = new Pen(bc, width))
        {
            myPen.LineJoin = LineJoin.Round;
            using (PathGradientBrush pgrbr = new PathGradientBrush(vertices))
            {
                pgrbr.CenterPoint = new Point(rpx, rpy);
                pgrbr.CenterColor = cc;
                pgrbr.SurroundColors = Ct;
                //switch (sides)
                //{
...

 

 

  • Upvote 1

Share this post


Link to post
Share on other sites
On ‎21‎/‎02‎/‎2018 at 8:07 PM, xod said:

This effect (Hystogram) was created in VisualStudio only to understand how things work.
It's about ConfigToken, ConfigDialog, InitTokenFromDialog, InitDialogFromToken, and so on.
So it can't be really considered as a plugin. Found in Effects > Render submenu.

I'm trying to add the color picker button to my hexagrid plugin. It seems ok but I'm facing a problem already present in your source code.

 

With your plugin Hystogram run the effect a first time and change the colors of the bars and some values, then Ok.

Open the effect another time, the colors on the buttons are back to initials colors. This isn't the usual behave of a plugin. I can't see how to make it works.

 

Extra trouble with the dark theme I had to remove the groupboxes because the fonts remain black....

 

HexaGridSRCv2.zip

Share this post


Link to post
Share on other sites
9 hours ago, MadJik said:

Open the effect another time, the colors on the buttons are back to initials colors.

 

You are setting the BackColors correctly from the EffectToken values, but then the BackColors get set to the defaults here:

private void ConfigDialog_Load(object sender, EventArgs e)
{
    ColPick1.BackColor = Color.Black;
    ColPick2.BackColor = Color.Black;
    ColPickSpot.BackColor = Color.Gray;
}

 

9 hours ago, MadJik said:

Extra trouble with the dark theme I had to remove the groupboxes because the fonts remain black....

 

Yeah, some of the standard WinForm controls have limitations in regards to their appearance. You may need to override some things, or create a custom control.

  • Like 1

Share this post


Link to post
Share on other sites

Oh, sorry, there's more to it than that. Some of your UI events invoke FinishTokenUpdate().  So, for example when you set AntiAliased.Checked = ..., it invokes FinishTokenUpdate(), which sets the Token values based on the current values of the controls. However, the color buttons have not yet been changed from their defaults.

 

Move the color stuff to the top, so they get set before the Token gets updated based on current UI controls. That fixes the issue.

protected override void InitDialogFromToken(EffectConfigToken effectToken)
{
    // This repopulates the UI when you run the effect a second time
    EffectPluginConfigToken token = (EffectPluginConfigToken)effectToken;
    Color1 = token.Color1;
    Color2 = token.Color2;
    ColorSpot = token.ColorSpot;
    colorDialog1.Color = Color1;
    colorDialog2.Color = Color2;
    colorDialogSpot.Color = ColorSpot;
    ColPick1.BackColor = Color1;
    ColPick2.BackColor = Color2;
    ColPickSpot.BackColor = ColorSpot;

    AntiAliased.Checked = token.AntiAliased;
    SpotCross.Checked = token.SpotCross;
    cbEnd.Checked = token.EndMode;
    DrawMode1.Checked = token.DrawMode1;
    DrawMode2.Checked = token.DrawMode2;
    DrawMode3.Checked = token.DrawMode3;
    DrawMode4.Checked = token.DrawMode4;
    DrawMode5.Checked = token.DrawMode5;
    DrawMode6.Checked = token.DrawMode6;
    AlphaUpDown.Value = token.TransAlpha;
    BrushUpDown.Value = token.BrushWidth;
    SizeUpDown.Value = token.SizeHexa;
    SizbUpDown.Value = token.SizeHexb;
    cbSize.Checked = token.SizeLink;
}

 

  • Like 1

Share this post


Link to post
Share on other sites

This little plugin is based on the Rainbow Torus posted by klaxxon in the Creations thread.

 

Spoiler

// Name: Circular shapes
// Submenu: Render
// Author: xod
// Title: Circular shapes
// Version: 1.0
// Desc: Render some circular shapes
// Keywords: Circular shapes
// URL: https://forums.getpaint.net
// Help:
#region UICode

DoubleSliderControl Amount1 = 0.56; // [0.1,1] RING:   Size, Color, Thickness
ColorWheelControl Amount2 = ColorBgra.FromBgr(0,255,255); // [Yellow] {Amount5} 
DoubleSliderControl Amount3 = 0.36; // [0,1] 
CheckboxControl Amount4 = false; // [0,1] Thickness x 2
CheckboxControl Amount5 = true; // [0,1] Show the ring
IntSliderControl Amount6 = 1; // [1,300] PEN:   Size, Color, StartCap, EndCap
ColorWheelControl Amount7 = ColorBgra.FromBgr(0,0,255); // [Red] 
ListBoxControl Amount8 = 0; // {Amount10} |Flat|Round|Triangle|RoundAnchor|ArrowAnchor|SquareAnchor|DiamondAnchor
ListBoxControl Amount9 = 0; // {Amount10} |Flat|Round|Triangle|RoundAnchor|ArrowAnchor|SquareAnchor|DiamondAnchor
ListBoxControl Amount10 = 0; // SHAPES|Arc|Ellipse|Rectangle
IntSliderControl Amount11 = 12; // [1,100] Number of shapes
CheckboxControl Amount12 = false; // [0,1] {Amount10} Flip arcs
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

    float centerX = ((selection.Right - selection.Left) / 2f + selection.Left);
    float centerY = ((selection.Bottom - selection.Top) / 2f + selection.Top);
    float diam = (float)Amount1 * Math.Min(selection.Width, selection.Height);
    int thick = (int)(diam * Amount3);
    if (Amount4)
    {
        thick = (int)(Amount1 * 1199 * Amount3);
    }
    float radius = diam * 0.5f;
    float width = diam - thick * 0.5f;
    float height = diam;
    float pointX = centerX - radius;
    float pointY = centerY - radius;

    float coordX = centerX - radius - centerX + thick * 0.25f;
    float coordY = centerY - radius - centerY - thick * 0.5f;

    dst.CopySurface(src, rect.Location, rect);
    using (RenderArgs ra = new RenderArgs(dst))
    {
        Graphics g = ra.Graphics;
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.Clip = new Region(rect);

        using (Pen gPen = new Pen(Amount2, thick))
        {

            gPen.DashStyle = DashStyle.Solid;
            {
                if(Amount5) g.DrawEllipse(gPen, pointX, pointY, diam, diam);
                gPen.Width = Amount6;
                gPen.Color = Amount7;
                switch(Amount8)
                {
                    case 0:
                        gPen.StartCap = LineCap.Flat;
                        break;
                    case 1:
                        gPen.StartCap = LineCap.Round;
                        break;
                    case 2:
                        gPen.StartCap = LineCap.Triangle;
                        break;
                    case 3:
                        gPen.StartCap = LineCap.RoundAnchor;
                        break;
                    case 4:
                        gPen.StartCap = LineCap.ArrowAnchor;
                        break;
                    case 5:
                        gPen.StartCap = LineCap.SquareAnchor;
                        break;
                    case 6:
                        gPen.StartCap = LineCap.DiamondAnchor;
                        break;
                }
                switch(Amount9)
                {
                    case 0:
                        gPen.EndCap = LineCap.Flat;
                        break;
                    case 1:
                        gPen.EndCap = LineCap.Round;
                        break;
                    case 2:
                        gPen.EndCap = LineCap.Triangle;
                        break;
                    case 3:
                        gPen.EndCap = LineCap.RoundAnchor;
                        break;
                    case 4:
                        gPen.EndCap = LineCap.ArrowAnchor;
                        break;
                    case 5:
                        gPen.EndCap = LineCap.SquareAnchor;
                        break;
                    case 6:
                        gPen.EndCap = LineCap.DiamondAnchor;
                        break;
                }

                //point of rotation = center of canvas (selection)
                g.TranslateTransform(centerX, centerY);
                RectangleF r1 = new RectangleF(coordX, coordY, width, height);
                for (int NumberOfShapes = 0; NumberOfShapes < Amount11; NumberOfShapes++)
                {
                    float angle = 360f/Amount11;
                    g.RotateTransform(angle);
                    {
                        try
                        {
                            switch(Amount10)
                            {
                                case 0:
                                    if(Amount12) g.DrawArc(gPen, r1, 90, -180);
                                    else g.DrawArc(gPen, r1, -90, -180);
                                    break;
                                case 1:
                                    g.DrawEllipse(gPen, r1);
                                    break;
                                case 2:
                                    g.DrawRectangle(gPen, coordX, coordY, width, height);
                                    break;
                            }
                        }
                        catch{};
                    }
                }
            }
        }
    }
}

 

 

ring2.png.5999467cf41c70e02db156b5da9360a5.png

 

CircularShapes.zip

Edited by xod
Added dll file.
  • Like 1
  • Upvote 1

Share this post


Link to post
Share on other sites

This is my Circle Text plugin test. It can be improved.

 

Spoiler

// Name: Circle Text 2
// Submenu: Text Formations
// Author: xod
// Title:
// Version: 1.0
// Desc:
// Keywords:
// URL:
// Help:

#region UICode
TextboxControl Amount1 = "Test top text"; // [0,255] Top text
TextboxControl Amount2 = "Test bottom test"; // [0,255] Bottom text
IntSliderControl Amount3 = 35; // [5,100] Text size
IntSliderControl Amount4 = 0; // [-1000,1000] Adjust position
RadioButtonControl Amount5 = 0; // [1] |Top|Bottom
FontFamily Amount6 = new FontFamily("Arial"); // Font
CheckboxControl Amount7 = false; // [0,1] Bold
CheckboxControl Amount8 = false; // [0,1] Italic
ColorWheelControl Amount9 = ColorBgra.FromBgr(0,0,0); //
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

    dst.CopySurface(src, rect.Location, rect);

    using (RenderArgs ra = new RenderArgs(dst))
    {
        Graphics g = ra.Graphics;
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.TextRenderingHint = TextRenderingHint.AntiAlias;
        StringFormat format = new StringFormat();
        format.Alignment = StringAlignment.Center;
        format.LineAlignment = StringAlignment.Center;
        Font SelectedFont = new Font(Amount6, Amount3);
        FontStyle myStyle = FontStyle.Regular;
        if (Amount7) myStyle |= FontStyle.Bold;
        if (Amount8) myStyle |= FontStyle.Italic;

        g.Clip = new Region(rect);

        using(SolidBrush sBrush = new SolidBrush(Amount9))
        {
            float font_height = Amount3;
            float radius = Math.Min(selection.Width, selection.Height) / 2 - 2.5f * font_height;
            float diam = 2 * radius;
            float cx = selection.Width / 2;
            float cy = selection.Height / 2;

            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.TextRenderingHint = TextRenderingHint.AntiAlias;

            // Make a font to use.
            using (Font font = new Font(SelectedFont, myStyle))
            {
                // Draw the circle
                //g.DrawEllipse(Pens.Red, cx - radius, cy - radius, diam, diam);

                // Draw the text.
                DrawTextOnCircle(g, font, sBrush, radius, cx, cy, Amount1, Amount2);
            }
        }
    }
}

private void DrawTextOnCircle(Graphics g, Font font, Brush brush, float radius, float cx, float cy, string top_text, string bottom_text)
{
    double width_to_angle = 1 / radius;
    using (StringFormat string_format = new StringFormat())
    {
        string_format.Alignment = StringAlignment.Center;
        string_format.LineAlignment = StringAlignment.Far;
        float text_width = Amount4;
        // Used to scale from radians to degrees
        double radians_to_degrees = 180.0 / Math.PI;
        switch (Amount5)
        {
            case 0: //Draw the top text
                List<RectangleF> rects = MeasureCharacters(g, font, top_text);
                // Find the starting angle
                double start_angle = -Math.PI / 2 - text_width / 2 * width_to_angle;
                double theta = start_angle;
                // Draw the characters.
                for (int i = 0; i < top_text.Length; i++)
                {
                    // See where this character goes
                    theta += rects[i].Width / 2 * width_to_angle;
                    double x = cx + radius * Math.Cos(theta);
                    double y = cy + radius * Math.Sin(theta);
                    // Transform to position the character
                    g.RotateTransform((float)(radians_to_degrees * (theta + Math.PI / 2)));
                    g.TranslateTransform((float)x, (float)y, MatrixOrder.Append);
                    // Draw the character.
                    g.DrawString(top_text[i].ToString(), font, brush, 0, 0, string_format);
                    g.ResetTransform();
                    // Increment theta
                    theta += rects[i].Width / 2 * width_to_angle;
                }
                break;

            case 1: //Draw the bottom text
                rects = MeasureCharacters(g, font, bottom_text);
                // Find the starting angle
                start_angle = Math.PI / 2 + text_width / 2 * width_to_angle;
                theta = start_angle;
                string_format.Alignment = StringAlignment.Center;
                string_format.LineAlignment = StringAlignment.Near;
                // Draw the characters
                for (int i = 0; i < bottom_text.Length; i++)
                {
                    // See where this character goes
                    theta -= rects[i].Width / 2 * width_to_angle;
                    double x = cx + radius * Math.Cos(theta);
                    double y = cy + radius * Math.Sin(theta);
                    // Transform to position the character
                    g.RotateTransform((float)(radians_to_degrees * (theta - Math.PI / 2)));
                    g.TranslateTransform((float)x, (float)y, MatrixOrder.Append);
                    // Draw the character
                    g.DrawString(bottom_text[i].ToString(), font, brush, 0, 0, string_format);
                    g.ResetTransform();
                    // Increment theta
                    theta -= rects[i].Width / 2 * width_to_angle;
                }
                break;
        }
    }
}

private List<RectangleF> MeasureCharacters(Graphics gr, Font font, string text)
{
    List<RectangleF> results = new List<RectangleF>();
    // The X location for the next character
    float x = 0;
    // Get the character sizes 31 characters at a time
    for (int start = 0; start < text.Length; start += 32)
    {
        // Get the substring.
        int len = 32;
        if (start + len >= text.Length) len = text.Length - start;
        string substring = text.Substring(start, len);
        // Measure the characters.
        List<RectangleF> rects = MeasureCharactersInWord(gr, font, substring);
        // Remove lead-in for the first character
        if (start == 0) x += rects[0].Left;
        // Save all but the last rectangle
        for (int i = 0; i < rects.Count + 1 - 1; i++)
        {
            RectangleF new_rect = new RectangleF(x, rects[i].Top, rects[i].Width, rects[i].Height);
            results.Add(new_rect);
            // Move to the next character's X position
            x += rects[i].Width;
        }
    }
    return results;
}

// Measure the characters in a string with no more than 32 characters
private List<RectangleF> MeasureCharactersInWord(Graphics g, Font font, string text)
{
    List<RectangleF> result = new List<RectangleF>();

    using (StringFormat string_format = new StringFormat())
    {
        string_format.Alignment = StringAlignment.Near;
        string_format.LineAlignment = StringAlignment.Near;
        string_format.Trimming = StringTrimming.None;
        string_format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;

        CharacterRange[] ranges = new CharacterRange[text.Length];
        for (int i = 0; i < text.Length; i++)
        {
            ranges[i] = new CharacterRange(i, 1);
        }
        string_format.SetMeasurableCharacterRanges(ranges);
        // Find the character ranges
        RectangleF rect = new RectangleF(0, 0, 10000, 100);
        Region[] regions = g.MeasureCharacterRanges(text, font, rect, string_format);
        // Convert the regions into rectangles
        foreach (Region region in regions) result.Add(region.GetBounds(g));
    }
    return result;
}

 

 

  • Like 1
  • Upvote 1

Share this post


Link to post
Share on other sites

@xod i looked at this code and made some changes to it:

 

Amount3 is Double for more precision

 

(Amount4 might be an angle chooser…)

 

Amount5 added Both

 

(new)Amount6 to draw the circle

(may be add the external circle…)

 

In DrawTextOnCircle:

Added // Calculate the Start angle to have text centered.

 

Spoiler

// Name: Circle Text 2
// Submenu: Text Formations
// Author: xod
// Title:
// Version: 1.1
// Desc:
// Keywords:
// URL:
// Help:

#region UICode
TextboxControl Amount1 = "<==  Test  top  text   ==>"; // [0,255] Top text
TextboxControl Amount2 = "{--   Test  bottom  test   --}"; // [0,255] Bottom text
DoubleSliderControl Amount3 = 35; // [5,100] Text size
IntSliderControl Amount4 = 0; // [-1000,1000] Adjust position
RadioButtonControl Amount5 = 2; // [1] Draw|Top|Bottom|Both
CheckboxControl Amount6 = false; // [0,1] Draw the circle
FontFamily Amount7 = new FontFamily("Arial"); // Font
CheckboxControl Amount8 = false; // [0,1] Bold
CheckboxControl Amount9 = false; // [0,1] Italic
ColorWheelControl Amount10 = ColorBgra.FromBgr(0,0,0); //
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

    dst.CopySurface(src, rect.Location, rect);

    using (RenderArgs ra = new RenderArgs(dst))
    {
        Graphics g = ra.Graphics;
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.TextRenderingHint = TextRenderingHint.AntiAlias;
        StringFormat format = new StringFormat();
        format.Alignment = StringAlignment.Center;
        format.LineAlignment = StringAlignment.Center;
        Font SelectedFont = new Font(Amount7, (float)Amount3);
        FontStyle myStyle = FontStyle.Regular;
        if (Amount8) myStyle |= FontStyle.Bold;
        if (Amount9) myStyle |= FontStyle.Italic;

        g.Clip = new Region(rect);

        using(SolidBrush sBrush = new SolidBrush(Amount10))
        {
            float font_height = (float)Amount3;
            float radius = Math.Min(selection.Width, selection.Height) / 2 - 2.5f * font_height;
            float diam = 2 * radius;
            float cx = selection.Width / 2;
            float cy = selection.Height / 2;

            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.TextRenderingHint = TextRenderingHint.AntiAlias;

            // Make a font to use.
            using (Font font = new Font(SelectedFont, myStyle))
            {
                // Draw the circle
                if (Amount6) g.DrawEllipse(Pens.Red, cx - radius, cy - radius, diam, diam);

                // Draw the text.
                DrawTextOnCircle(g, font, sBrush, radius, cx, cy, Amount1, Amount2);
            }
        }
    }
}

private void DrawTextOnCircle(Graphics g, Font font, Brush brush, float radius, float cx, float cy, string top_text, string bottom_text)
{
    double width_to_angle = 1 / radius;
    using (StringFormat string_format = new StringFormat())
    {
        string_format.Alignment = StringAlignment.Center;
        string_format.LineAlignment = StringAlignment.Far;
        float text_width = Amount4;
        // Used to scale from radians to degrees
        double radians_to_degrees = 180.0 / Math.PI;

        if ((Amount5 ==0 || Amount5 ==2) && (top_text.Length>0))
        {//Draw the top text
            List<RectangleF> rects = MeasureCharacters(g, font, top_text);
            // Find the starting angle
            double start_angle = -Math.PI / 2 - text_width / 2 * width_to_angle;
            // Calculate the Start angle to have text centered.
            for (int i = 0; i < top_text.Length; i++)
            {
                start_angle -= rects[i].Width / 2 * width_to_angle;
            }

            double theta = start_angle;
            // Draw the characters.
            for (int i = 0; i < top_text.Length; i++)
            {
                // See where this character goes
                theta += rects[i].Width / 2 * width_to_angle;
                double x = cx + radius * Math.Cos(theta);
                double y = cy + radius * Math.Sin(theta);
                // Transform to position the character
                g.RotateTransform((float)(radians_to_degrees * (theta + Math.PI / 2)));
                g.TranslateTransform((float)x, (float)y, MatrixOrder.Append);
                // Draw the character.
                g.DrawString(top_text[i].ToString(), font, brush, 0, 0, string_format);
                g.ResetTransform();
                // Increment theta
                theta += rects[i].Width / 2 * width_to_angle;
            }
        }
        if ((Amount5 ==1 || Amount5 ==2) && (bottom_text.Length>0))
        {//Draw the bottom text
            List<RectangleF> rects = MeasureCharacters(g, font, bottom_text);
            // Find the starting angle
            double start_angle = Math.PI / 2 - text_width / 2 * width_to_angle;
            //Calculate the Start angle to have text centered.
            for (int i = 0; i < bottom_text.Length; i++)
            {
                start_angle += rects[i].Width / 2 * width_to_angle;
            }

            double theta = start_angle;
            string_format.Alignment = StringAlignment.Center;
            string_format.LineAlignment = StringAlignment.Near;
            // Draw the characters
            for (int i = 0; i < bottom_text.Length; i++)
            {
                // See where this character goes
                theta -= rects[i].Width / 2 * width_to_angle;
                double x = cx + radius * Math.Cos(theta);
                double y = cy + radius * Math.Sin(theta);
                // Transform to position the character
                g.RotateTransform((float)(radians_to_degrees * (theta - Math.PI / 2)));
                g.TranslateTransform((float)x, (float)y, MatrixOrder.Append);
                // Draw the character
                g.DrawString(bottom_text[i].ToString(), font, brush, 0, 0, string_format);
                g.ResetTransform();
                // Increment theta
                theta -= rects[i].Width / 2 * width_to_angle;
            }
        }
    }
}

private List<RectangleF> MeasureCharacters(Graphics gr, Font font, string text)
{
    List<RectangleF> results = new List<RectangleF>();
    // The X location for the next character
    float x = 0;
    // Get the character sizes 31 characters at a time
    for (int start = 0; start < text.Length; start += 32)
    {
        // Get the substring.
        int len = 32;
        if (start + len >= text.Length) len = text.Length - start;
        string substring = text.Substring(start, len);
        // Measure the characters.
        List<RectangleF> rects = MeasureCharactersInWord(gr, font, substring);
        // Remove lead-in for the first character
        if (start == 0) x += rects[0].Left;
        // Save all but the last rectangle
        for (int i = 0; i < rects.Count + 1 - 1; i++)
        {
            RectangleF new_rect = new RectangleF(x, rects[i].Top, rects[i].Width, rects[i].Height);
            results.Add(new_rect);
            // Move to the next character's X position
            x += rects[i].Width;
        }
    }
    return results;
}

// Measure the characters in a string with no more than 32 characters
private List<RectangleF> MeasureCharactersInWord(Graphics g, Font font, string text)
{
    List<RectangleF> result = new List<RectangleF>();

    using (StringFormat string_format = new StringFormat())
    {
        string_format.Alignment = StringAlignment.Near;
        string_format.LineAlignment = StringAlignment.Near;
        string_format.Trimming = StringTrimming.None;
        string_format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;

        CharacterRange[] ranges = new CharacterRange[text.Length];
        for (int i = 0; i < text.Length; i++)
        {
            ranges[i] = new CharacterRange(i, 1);
        }
        string_format.SetMeasurableCharacterRanges(ranges);
        // Find the character ranges
        RectangleF rect = new RectangleF(0, 0, 10000, 100);
        Region[] regions = g.MeasureCharacterRanges(text, font, rect, string_format);
        // Convert the regions into rectangles
        foreach (Region region in regions) result.Add(region.GetBounds(g));
    }
    return result;
}

 

 

Circle_Text_V2.gif

  • Like 2
  • Upvote 3

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.