Jump to content

Recommended Posts

Posted (edited)

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
Posted

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)
{
}

 

 

 

 

 

Posted

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;

 

Posted (edited)

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
Posted (edited)

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
Posted

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
Posted

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?

Posted

@xod   I see some very great potential in this plugin.  Thank you!   <3

 

A fiery gem!   :D

 

gradshape_01.png

 

  • Like 1
Posted

@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
  • 1 month later...
Posted
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

Posted
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
Posted

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
  • 2 months later...
Posted (edited)

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
  • 2 months later...
Posted

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
Posted

@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
Posted (edited)

Thought I'd share my WiP. It turns images into an array of isometric tiles that fit into a mesh. Sooo, it's not great. But... it's a start, I guess.

 

i9cXOOr.png

becomes

image.png.40ff97b02afbc9ef23e9aa56caaf0f50.png

becomes

Lzp8mv8.png

Edited by Mallaboro

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.

×
×
  • Create New...